parent
0ec2777af0
commit
4a8453dd0d
20 changed files with 382 additions and 55 deletions
|
@ -5,7 +5,7 @@ namespace Baikal\Core;
|
|||
class ClassLoader {
|
||||
|
||||
public static function register() {
|
||||
return spl_autoload_register(array(get_called_class(), 'loadClass'));
|
||||
return spl_autoload_register(array(__CLASS__, 'loadClass'));
|
||||
}
|
||||
|
||||
public static function loadClass($sFullClassName) {
|
||||
|
|
|
@ -7,10 +7,21 @@ class Form extends \Flake\Core\Controler {
|
|||
const BASEPATH = "/admin/";
|
||||
protected $aMessages = array();
|
||||
|
||||
function execute() {
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
if(($iUser = self::editRequested()) !== FALSE) {
|
||||
if(self::editSubmitted()) {
|
||||
|
||||
$this->oModel = new \BaikalAdmin\Model\User($iUser);
|
||||
}
|
||||
|
||||
$this->initForm();
|
||||
}
|
||||
|
||||
function execute() {
|
||||
|
||||
if(($iUser = self::editRequested()) !== FALSE) {
|
||||
if($this->oForm->submitted()) {
|
||||
$this->oForm->execute();
|
||||
/*
|
||||
$aPost = \Flake\Util\Tools::POST();
|
||||
$aErrors = array();
|
||||
|
||||
|
@ -44,7 +55,7 @@ class Form extends \Flake\Core\Controler {
|
|||
"Changes on <i class='icon-user'></i> <strong>" . $oUser->get("username") . "</strong> have been saved."
|
||||
);
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,7 +86,21 @@ class Form extends \Flake\Core\Controler {
|
|||
self::BASEPATH
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function initForm() {
|
||||
$aOptions = array(
|
||||
"closeurl" => $this::BASEPATH
|
||||
);
|
||||
|
||||
if($this->editRequested()) {
|
||||
$this->oForm = $this->oModel->formForInstance($aOptions);
|
||||
} else {
|
||||
$this->oForm = \BaikalAdmin\Model\User::formEmpty(array(
|
||||
"closeurl" => $this::BASEPATH
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
public static function editRequested() {
|
||||
|
@ -86,12 +111,6 @@ class Form extends \Flake\Core\Controler {
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
public static function editSubmitted() {
|
||||
return self::editRequested() && (
|
||||
intval(\Flake\Util\Tools::POST("formedit-submitted")) === 1
|
||||
);
|
||||
}
|
||||
|
||||
public static function deleteRequested() {
|
||||
if(($iUser = intval(\Flake\Util\Tools::GET("userdel"))) > 0) {
|
||||
return $iUser;
|
||||
|
@ -124,7 +143,9 @@ class Form extends \Flake\Core\Controler {
|
|||
$oView->setData("user", $oUser);
|
||||
$oView->setData("messages", $sMessages);
|
||||
|
||||
$sHtml .= $this->oForm->render();
|
||||
$sHtml .= $oView->render();
|
||||
|
||||
} else {
|
||||
$sHtml .= $sMessages;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,9 @@ require_once(dirname(dirname(dirname(__FILE__))) . "/Baikal/Core/Bootstrap.php")
|
|||
# Bootstrap Flake
|
||||
require_once(dirname(dirname(dirname(__FILE__))) . "/Flake/Core/Bootstrap.php");
|
||||
|
||||
# Bootstrap Formal
|
||||
require_once(dirname(dirname(dirname(__FILE__))) . "/Formal/Core/Bootstrap.php");
|
||||
|
||||
# Registering BaikalAdmin classloader
|
||||
require_once(dirname(__FILE__) . '/ClassLoader.php');
|
||||
\BaikalAdmin\Core\ClassLoader::register();
|
||||
|
|
|
@ -5,7 +5,7 @@ namespace BaikalAdmin\Core;
|
|||
class ClassLoader {
|
||||
|
||||
public static function register() {
|
||||
return spl_autoload_register(array(get_called_class(), 'loadClass'));
|
||||
return spl_autoload_register(array(__CLASS__, 'loadClass'));
|
||||
}
|
||||
|
||||
public static function loadClass($sFullClassName) {
|
||||
|
|
|
@ -5,6 +5,7 @@ namespace BaikalAdmin\Model;
|
|||
class User extends \Flake\Core\Model\Db {
|
||||
const DATATABLE = "users";
|
||||
const PRIMARYKEY = "id";
|
||||
const LABELFIELD = "username";
|
||||
|
||||
protected $oIdentityPrincipal = null;
|
||||
|
||||
|
@ -56,4 +57,37 @@ class User extends \Flake\Core\Model\Db {
|
|||
public function getMailtoURI() {
|
||||
return "mailto:" . rawurlencode($this->get("displayname") . " <" . $this->get("email") . ">");
|
||||
}
|
||||
|
||||
# Empty form,
|
||||
public static function formEmpty($options = array()) {
|
||||
$sClass = get_called_class();
|
||||
$oForm = new \Formal\Core\Form($sClass, $options);
|
||||
|
||||
$oForm->add(new \Formal\Element\Text(array(
|
||||
"prop" => "username",
|
||||
"label" => "Username",
|
||||
"validation" => "required"
|
||||
)));
|
||||
|
||||
$oForm->add(new \Formal\Element\Text(array(
|
||||
"prop" => "displayname",
|
||||
"label" => "Display name",
|
||||
"validation" => "required"
|
||||
)));
|
||||
|
||||
$oForm->add(new \Formal\Element\Text(array(
|
||||
"prop" => "email",
|
||||
"label" => "Email",
|
||||
"validation" => "required,email"
|
||||
)));
|
||||
|
||||
return $oForm;
|
||||
}
|
||||
|
||||
public function formForInstance($options = array()) {
|
||||
$oForm = self::formEmpty($options)->setModelInstance($this);
|
||||
$oForm->element("username")->setOption("readonly", true);
|
||||
|
||||
return $oForm;
|
||||
}
|
||||
}
|
|
@ -1,30 +1 @@
|
|||
<form class="form-horizontal" action="<?= $action ?>" method="post" enctype="multipart/formdata">
|
||||
<input type="hidden" name="formedit-submitted" value="1" />
|
||||
<fieldset>
|
||||
<legend>Editing user <strong><?= $user->get("username") ?></strong></legend>
|
||||
<?= $messages ?>
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="disabledInput">Username</label>
|
||||
<div class="controls">
|
||||
<input class="input-xlarge disabled" id="username" type="text" placeholder="<?= htmlspecialchars($user->get("username")) ?>" disabled="" />
|
||||
<!--p class="help-block">The username is readonly, and may not be changed.</p-->
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="displayname">Display name</label>
|
||||
<div class="controls">
|
||||
<input type="text" class="input-xlarge" id="displayname" name="displayname" value="<?= htmlspecialchars($user->get("displayname")) ?>"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="displayname">Email</label>
|
||||
<div class="controls">
|
||||
<input type="text" class="input-xlarge" id="email" name="email" value="<?= htmlspecialchars($user->get("email")) ?>"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
<button type="submit" class="btn btn-primary">Save changes</button>
|
||||
<a class="btn" href="<?= $linkcancel ?>">Close</a>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
<?= $messages ?>
|
||||
|
|
|
@ -29,6 +29,7 @@ require_once(FLAKE_PATH_ROOT . 'Core/ClassLoader.php');
|
|||
require_once(FLAKE_PATH_ROOT . "config.php");
|
||||
|
||||
if(!\Flake\Util\Tools::isCliPhp()) {
|
||||
ini_set("html_errors", TRUE);
|
||||
session_start();
|
||||
\Flake\Util\Tools::decode_GET();
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ namespace Flake\Core;
|
|||
class ClassLoader {
|
||||
|
||||
public static function register() {
|
||||
return spl_autoload_register(array(get_called_class(), 'loadClass'));
|
||||
return spl_autoload_register(array(__CLASS__, 'loadClass'));
|
||||
}
|
||||
|
||||
public static function loadClass($sFullClassName) {
|
||||
|
|
|
@ -26,6 +26,15 @@ class Collection extends \Flake\Core\FLObject implements \Iterator {
|
|||
$key = key($this->aCollection);
|
||||
return ($key !== NULL && $key !== FALSE);
|
||||
}
|
||||
|
||||
public function getForKey($sKey) {
|
||||
$aKeys = $this->keys();
|
||||
if(!in_array($sKey, $aKeys)) {
|
||||
throw new \Exception("\Flake\Core\Collection->getForKey(): key '" . $sKey . "' not found in Collection");
|
||||
}
|
||||
|
||||
return $this->aCollection[$sKey];
|
||||
}
|
||||
|
||||
public function &each() {
|
||||
list($key, $val) = each($this->aCollection);
|
||||
|
@ -126,6 +135,14 @@ class Collection extends \Flake\Core\FLObject implements \Iterator {
|
|||
public function toArray() {
|
||||
return $this->aCollection;
|
||||
}
|
||||
|
||||
# Create a new collection like this one
|
||||
# This abstraction is useful because of CollectionTyped
|
||||
|
||||
protected function newCollectionLikeThisOne() {
|
||||
$oCollection = \Flake\Core\Collection();
|
||||
return $oCollection;
|
||||
}
|
||||
|
||||
/*
|
||||
* Méthode magique __call
|
||||
|
|
|
@ -30,4 +30,12 @@ class CollectionTyped extends \Flake\Core\Collection {
|
|||
|
||||
parent::push($mMixed);
|
||||
}
|
||||
|
||||
# Create a new collection like this one
|
||||
# This abstraction is useful because of CollectionTyped
|
||||
|
||||
protected function newCollectionLikeThisOne() {
|
||||
$oCollection = \Flake\Core\CollectionTyped($this->sTypeClassOrProtocol);
|
||||
return $oCollection;
|
||||
}
|
||||
}
|
|
@ -7,8 +7,16 @@ class FLObject {
|
|||
return print_r($this, TRUE);
|
||||
}
|
||||
|
||||
public static function getClass() {
|
||||
return get_called_class();
|
||||
public function getClass() {
|
||||
// throw new \Exception("getClass() is deprecated");
|
||||
if(!isset($this)) {
|
||||
# echo "STATIC<br />";
|
||||
return get_called_class();
|
||||
} else {
|
||||
# echo "INSTANCE<br />";
|
||||
# debug($this);
|
||||
return get_class($this);
|
||||
}
|
||||
}
|
||||
|
||||
public function isA($sClassOrProtocolName) {
|
||||
|
|
|
@ -26,4 +26,8 @@ abstract class Model extends \Flake\Core\FLObject {
|
|||
|
||||
throw new \Exception("\Flake\Core\Model->set(): property " . htmlspecialchars($sPropName) . " does not exist on " . self::getClass());
|
||||
}
|
||||
|
||||
public function getLabel() {
|
||||
return $this->get($this::LABELFIELD);
|
||||
}
|
||||
}
|
|
@ -428,16 +428,16 @@ TEST;
|
|||
public static function is_a($object, $class) {
|
||||
if(is_object($object)) return $object instanceof $class;
|
||||
if(is_string($object)){
|
||||
if(is_object($class)) $class=get_class($class);
|
||||
if(is_object($class)) $class=get_class($class);
|
||||
|
||||
if(class_exists($class)) return is_subclass_of($object, $class) || $object==$class;
|
||||
if(interface_exists($class)) {
|
||||
$reflect = new \ReflectionClass($object);
|
||||
return $reflect->implementsInterface($class);
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
if(class_exists($class)) return is_subclass_of($object, $class) || $object==$class;
|
||||
if(interface_exists($class)) {
|
||||
$reflect = new \ReflectionClass($object);
|
||||
return $reflect->implementsInterface($class);
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function HTTPStatus($iCode, $sMessage) {
|
||||
|
|
9
CoreVersions/Baikal_0.1/Frameworks/Formal/Core.php
Normal file
9
CoreVersions/Baikal_0.1/Frameworks/Formal/Core.php
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Formal;
|
||||
|
||||
class Core {
|
||||
public static function handle($sName) {
|
||||
debug("Handling " . $sName);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
define("FORMAL_PATH_ROOT", dirname(dirname(__FILE__)) . "/");
|
||||
|
||||
# Registering BaikalAdmin classloader
|
||||
require_once(dirname(__FILE__) . '/ClassLoader.php');
|
||||
\Formal\Core\ClassLoader::register();
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace Formal\Core;
|
||||
|
||||
class ClassLoader {
|
||||
|
||||
public static function register() {
|
||||
return spl_autoload_register(array(__CLASS__, 'loadClass'));
|
||||
}
|
||||
|
||||
public static function loadClass($sFullClassName) {
|
||||
|
||||
$aParts = explode("\\", $sFullClassName);
|
||||
if(count($aParts) === 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if($aParts[0] !== "Formal") {
|
||||
return;
|
||||
}
|
||||
|
||||
// ejecting the Radical
|
||||
$sRadical = array_shift($aParts);
|
||||
|
||||
if($sRadical === "Formal") {
|
||||
$sRootPath = FORMAL_PATH_ROOT;
|
||||
}
|
||||
|
||||
$sClassName = array_pop($aParts);
|
||||
$sBasePath = $sRootPath . implode("/", $aParts) . "/";
|
||||
$sClassPath = $sBasePath . $sClassName . ".php";
|
||||
|
||||
if(file_exists($sClassPath) && is_readable($sClassPath)) {
|
||||
require_once($sClassPath);
|
||||
} else {
|
||||
echo '<h1>PHP Autoload Error. Cannot find ' . $sFullClassName . '</h1>';
|
||||
echo "<pre>" . print_r(debug_backtrace(), TRUE) . "</pre>";
|
||||
die();
|
||||
}
|
||||
}
|
||||
}
|
139
CoreVersions/Baikal_0.1/Frameworks/Formal/Core/Form.php
Normal file
139
CoreVersions/Baikal_0.1/Frameworks/Formal/Core/Form.php
Normal file
|
@ -0,0 +1,139 @@
|
|||
<?php
|
||||
|
||||
namespace Formal\Core;
|
||||
|
||||
class Form {
|
||||
|
||||
protected $sModelClass = "";
|
||||
protected $aOptions = array();
|
||||
protected $oModelInstance = null;
|
||||
protected $oElements = null;
|
||||
|
||||
public function __construct($sModelClass, $aOptions = array()) {
|
||||
$this->sModelClass = $sModelClass;
|
||||
$this->aOptions = array_merge($this->aOptions, $aOptions);
|
||||
$this->oElements = new \Flake\Core\CollectionTyped("\Formal\Element");
|
||||
}
|
||||
|
||||
public function option($sName) {
|
||||
return $this->aOptions[$sName];
|
||||
}
|
||||
|
||||
public function setModelInstance($oModelInstance) {
|
||||
if(!\Flake\Util\Tools::is_a($oModelInstance, $this->sModelClass)) {
|
||||
throw new \Exception("\Formal\Core->setModelInstance(): Given instance is not of class '" . $this->sModelClass . "'");
|
||||
}
|
||||
|
||||
$this->oModelInstance = $oModelInstance;
|
||||
|
||||
$this->oElements->reset();
|
||||
foreach($this->oElements as $oElement) {
|
||||
$oElement->setValue(
|
||||
$this->getModelInstance()->get(
|
||||
$oElement->option("prop")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getModelInstance() {
|
||||
return $this->oModelInstance;
|
||||
}
|
||||
|
||||
public function hasModelInstance() {
|
||||
return !is_null($this->getModelInstance());
|
||||
}
|
||||
|
||||
public function add(\Formal\Element $oElement) {
|
||||
$this->oElements->push($oElement);
|
||||
}
|
||||
|
||||
public function element($sPropName) {
|
||||
$this->oElements->reset();
|
||||
foreach($this->oElements as $oElement) {
|
||||
if($oElement->option("prop") === $sPropName) {
|
||||
return $oElement;
|
||||
}
|
||||
}
|
||||
|
||||
throw new \Exception("\Formal\Core\Form->element(): Element prop='" . $sPropName . "' not found");
|
||||
}
|
||||
|
||||
public function execute() {
|
||||
if(!$this->hasModelInstance()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->oElements->reset();
|
||||
foreach($this->oElements as $oElement) {
|
||||
# If element is readonly, skip process
|
||||
if($oElement->option("readonly")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$sPropName = $oElement->option("prop");
|
||||
|
||||
# posted value is fetched, then passes to element before persistance
|
||||
$sPostValue = $this->postValue($sPropName);
|
||||
$oElement->setValue($sPostValue);
|
||||
|
||||
$this->getModelInstance()->set(
|
||||
$sPropName,
|
||||
$oElement->value()
|
||||
);
|
||||
}
|
||||
|
||||
$this->getModelInstance()->persist();
|
||||
}
|
||||
|
||||
public function postValue($sPropName) {
|
||||
# could be as well \Flake\Util\Tools::POST($sPropName)
|
||||
return \Flake\Util\Tools::POST($this->element($sPropName)->option("prop"));
|
||||
}
|
||||
|
||||
public function render() {
|
||||
$aHtml = array();
|
||||
|
||||
$this->oElements->reset();
|
||||
foreach($this->oElements as $oElement) {
|
||||
$aHtml[] = $oElement->render();
|
||||
}
|
||||
|
||||
$elements = implode("\n", $aHtml);
|
||||
|
||||
if($this->hasModelInstance()) {
|
||||
$sTitle = "Editing " . $this->getHumanModelName() . " <strong>" . $this->getModelInstance()->getLabel() . "</strong>";
|
||||
} else {
|
||||
$sTitle = "Creating new " . $this->getHumanModelName();
|
||||
}
|
||||
|
||||
$sSubmittedFlagName = $this->sModelClass . "::submitted";
|
||||
$sCloseUrl = $this->option("closeurl");
|
||||
|
||||
$sHtml =<<<HTML
|
||||
<form class="form-horizontal" action="" method="post" enctype="multipart/formdata">
|
||||
<input type="hidden" name="{$sSubmittedFlagName}" value="1" />
|
||||
<fieldset>
|
||||
<legend>{$sTitle}</legend>
|
||||
{$elements}
|
||||
<div class="form-actions">
|
||||
<button type="submit" class="btn btn-primary">Save changes</button>
|
||||
<a class="btn" href="{$sCloseUrl}">Close</a>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
HTML;
|
||||
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
public function submitted() {
|
||||
return intval(\Flake\Util\Tools::POST($this->sModelClass . "::submitted")) === 1;
|
||||
}
|
||||
|
||||
public function getHumanModelName() {
|
||||
return array_pop(explode("\\", $this->sModelClass));
|
||||
}
|
||||
}
|
35
CoreVersions/Baikal_0.1/Frameworks/Formal/Element.php
Normal file
35
CoreVersions/Baikal_0.1/Frameworks/Formal/Element.php
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace Formal;
|
||||
|
||||
class Element {
|
||||
protected $aOptions = array(
|
||||
"readonly" => FALSE,
|
||||
);
|
||||
|
||||
protected $sValue = "";
|
||||
|
||||
public function __construct($aOptions) {
|
||||
$this->aOptions = array_merge($aOptions, $this->aOptions);
|
||||
}
|
||||
|
||||
public function option($sName) {
|
||||
if(array_key_exists($sName, $this->aOptions)) {
|
||||
return $this->aOptions[$sName];
|
||||
}
|
||||
|
||||
throw new \Exception("\Formal\Element->option(): Option '" . htmlspecialchars($sName) . "' not found.");
|
||||
}
|
||||
|
||||
public function setOption($sOptionName, $sOptionValue) {
|
||||
$this->aOptions[$sOptionName] = $sOptionValue;
|
||||
}
|
||||
|
||||
public function value() {
|
||||
return $this->sValue;
|
||||
}
|
||||
|
||||
public function setValue($sValue) {
|
||||
$this->sValue = $sValue;
|
||||
}
|
||||
}
|
29
CoreVersions/Baikal_0.1/Frameworks/Formal/Element/Text.php
Normal file
29
CoreVersions/Baikal_0.1/Frameworks/Formal/Element/Text.php
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace Formal\Element;
|
||||
|
||||
class Text extends \Formal\Element {
|
||||
|
||||
public function render() {
|
||||
$value = htmlspecialchars($this->value());
|
||||
$label = $this->option("label");
|
||||
$prop = $this->option("prop");
|
||||
$disabled = "";
|
||||
$class = "";
|
||||
|
||||
if($this->option("readonly") === TRUE) {
|
||||
$class = " disabled";
|
||||
$disabled = " disabled";
|
||||
}
|
||||
|
||||
$sHtml =<<<HTML
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="displayname">{$label}</label>
|
||||
<div class="controls">
|
||||
<input type="text" class="input-xlarge{$sClass}" id="{$prop}" name="{$prop}" value="{$value}"{$disabled} />
|
||||
</div>
|
||||
</div>
|
||||
HTML;
|
||||
return $sHtml;
|
||||
}
|
||||
}
|
Binary file not shown.
Loading…
Reference in a new issue