Formal is now a git submodule, pointing to https://github.com/jeromeschneider/Formal.git
This commit is contained in:
parent
3984b17c84
commit
1333353921
12 changed files with 4 additions and 1096 deletions
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -1,3 +1,6 @@
|
|||
[submodule "CoreVersions/0.2.1/Frameworks/Flake"]
|
||||
path = CoreVersions/0.2.1/Frameworks/Flake
|
||||
url = https://github.com/jeromeschneider/Flake.git
|
||||
[submodule "CoreVersions/0.2.1/Frameworks/Formal"]
|
||||
path = CoreVersions/0.2.1/Frameworks/Formal
|
||||
url = https://github.com/jeromeschneider/Formal.git
|
||||
|
|
1
CoreVersions/0.2.1/Frameworks/Formal
Submodule
1
CoreVersions/0.2.1/Frameworks/Formal
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit d83f38d3880a82650ea4f93c815a8211245f58fe
|
|
@ -1,65 +0,0 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://formal.codr.fr
|
||||
#
|
||||
# This script is part of the Formal project. The Formal
|
||||
# project is free software; you can redistribute it
|
||||
# and/or modify it under the terms of the GNU General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2 of the License, or (at your option) any later version.
|
||||
#
|
||||
# The GNU General Public License can be found at
|
||||
# http://www.gnu.org/copyleft/gpl.html.
|
||||
#
|
||||
# This script is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# This copyright notice MUST APPEAR in all copies of the script!
|
||||
#################################################################
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://formal.codr.fr
|
||||
#
|
||||
# This script is part of the Formal project. The Formal
|
||||
# project is free software; you can redistribute it
|
||||
# and/or modify it under the terms of the GNU General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2 of the License, or (at your option) any later version.
|
||||
#
|
||||
# The GNU General Public License can be found at
|
||||
# http://www.gnu.org/copyleft/gpl.html.
|
||||
#
|
||||
# This script is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# This copyright notice MUST APPEAR in all copies of the script!
|
||||
#################################################################
|
||||
|
||||
namespace Formal\Core;
|
||||
|
||||
class Message {
|
||||
private function __construct() {
|
||||
}
|
||||
|
||||
public static function error($sMessage, $sTitle = "") {
|
||||
if($sTitle !== "") {
|
||||
$sTitle = '<h3 class="alert-heading">' . $sTitle . '</h3>';
|
||||
}
|
||||
|
||||
$sHtml =<<<HTML
|
||||
<div id="message" class="alert alert-block alert-error">
|
||||
{$sTitle}
|
||||
{$sMessage}
|
||||
</div>
|
||||
HTML;
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
public static function notice($sMessage, $sTitle = "", $bClose = TRUE) {
|
||||
$sClose = "";
|
||||
|
||||
if($sTitle !== "") {
|
||||
$sTitle = '<h3 class="alert-heading">' . $sTitle . '</h3>';
|
||||
}
|
||||
|
||||
if($bClose === TRUE) {
|
||||
$sClose = '<a class="close" data-dismiss="alert" href="#">×</a>';
|
||||
}
|
||||
|
||||
$sHtml =<<<HTML
|
||||
<div id="message" class="alert alert-info">
|
||||
{$sClose}
|
||||
{$sTitle}
|
||||
{$sMessage}
|
||||
</div>
|
||||
HTML;
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
public static function warningConfirmMessage($sHeader, $sDescription, $sActionUrl, $sActionLabel, $sCancelUrl, $sCancelLabel="Cancel") {
|
||||
$sHtml =<<<HTML
|
||||
<div id="message" class="alert alert-block alert-error">
|
||||
<!--a class="close" data-dismiss="alert" href="#">×</a-->
|
||||
<h3 class="alert-heading">{$sHeader}</h3>
|
||||
{$sDescription}
|
||||
<p>
|
||||
<a class="btn btn-danger" href="{$sActionUrl}">{$sActionLabel}</a> <a class="btn" href="{$sCancelUrl}">Cancel</a>
|
||||
</p>
|
||||
</div>
|
||||
HTML;
|
||||
return $sHtml;
|
||||
}
|
||||
}
|
|
@ -1,100 +0,0 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://formal.codr.fr
|
||||
#
|
||||
# This script is part of the Formal project. The Formal
|
||||
# project is free software; you can redistribute it
|
||||
# and/or modify it under the terms of the GNU General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2 of the License, or (at your option) any later version.
|
||||
#
|
||||
# The GNU General Public License can be found at
|
||||
# http://www.gnu.org/copyleft/gpl.html.
|
||||
#
|
||||
# This script is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# This copyright notice MUST APPEAR in all copies of the script!
|
||||
#################################################################
|
||||
|
||||
namespace Formal;
|
||||
|
||||
abstract class Element {
|
||||
|
||||
protected $aOptions = array(
|
||||
"class" => "",
|
||||
"inputclass" => "input-xlarge",
|
||||
"readonly" => FALSE,
|
||||
"validation" => "",
|
||||
"error" => FALSE,
|
||||
"placeholder" => "",
|
||||
"help" => "",
|
||||
"popover" => "",
|
||||
"refreshonchange" => FALSE,
|
||||
);
|
||||
|
||||
protected $sValue = "";
|
||||
|
||||
public function __construct($aOptions) {
|
||||
$this->aOptions = array_merge($this->aOptions, $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 optionArray($sOptionName) {
|
||||
$sOption = trim($this->option($sOptionName));
|
||||
if($sOption !== "") {
|
||||
$aOptions = explode(",", $sOption);
|
||||
} else {
|
||||
$aOptions = array();
|
||||
}
|
||||
|
||||
reset($aOptions);
|
||||
return $aOptions;
|
||||
}
|
||||
|
||||
public function setOption($sOptionName, $sOptionValue) {
|
||||
$this->aOptions[$sOptionName] = $sOptionValue;
|
||||
}
|
||||
|
||||
public function value() {
|
||||
return $this->sValue;
|
||||
}
|
||||
|
||||
public function setValue($sValue) {
|
||||
$this->sValue = $sValue;
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
return get_class($this) . "<" . $this->option("label") . ">";
|
||||
}
|
||||
|
||||
public function renderWitness() {
|
||||
return '<input type="hidden" name="witness[' . $this->option("prop") . ']" value="1" />';
|
||||
}
|
||||
|
||||
public function posted() {
|
||||
$aPost = \Flake\Util\Tools::POST("witness");
|
||||
if(is_array($aPost)) {
|
||||
$sProp = $this->option("prop");
|
||||
return (array_key_exists($sProp, $aPost)) && (intval($aPost[$sProp]) === 1);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
public abstract function render();
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://formal.codr.fr
|
||||
#
|
||||
# This script is part of the Formal project. The Formal
|
||||
# project is free software; you can redistribute it
|
||||
# and/or modify it under the terms of the GNU General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2 of the License, or (at your option) any later version.
|
||||
#
|
||||
# The GNU General Public License can be found at
|
||||
# http://www.gnu.org/copyleft/gpl.html.
|
||||
#
|
||||
# This script is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# This copyright notice MUST APPEAR in all copies of the script!
|
||||
#################################################################
|
||||
|
||||
namespace Formal\Element;
|
||||
|
||||
class Checkbox extends \Formal\Element {
|
||||
|
||||
public function setValue($sValue) {
|
||||
# Boolean
|
||||
$this->sValue = ((intval($sValue) === 1));
|
||||
}
|
||||
|
||||
public function render() {
|
||||
$disabled = "";
|
||||
$inputclass = "";
|
||||
$groupclass = "";
|
||||
$onchange = "";
|
||||
$helpblock = "";
|
||||
$popover = "";
|
||||
|
||||
$value = $this->value();
|
||||
|
||||
$checked = ($value === TRUE ? " checked=\"checked\" " : "");
|
||||
$label = $this->option("label");
|
||||
$prop = $this->option("prop");
|
||||
|
||||
if($this->option("readonly") === TRUE) {
|
||||
$inputclass .= " disabled";
|
||||
$disabled = " disabled";
|
||||
}
|
||||
|
||||
if($this->option("error") === TRUE) {
|
||||
$groupclass .= " error";
|
||||
}
|
||||
|
||||
if(($sHelp = trim($this->option("help"))) !== "") {
|
||||
$helpblock = "<p class=\"help-block\">" . $sHelp . "</p>";
|
||||
}
|
||||
|
||||
if(($aPopover = $this->option("popover")) !== "") {
|
||||
$inputclass .= " popover-hover ";
|
||||
$popover = " title=\"" . htmlspecialchars($aPopover["title"]) . "\" ";
|
||||
$popover .= " data-content=\"" . htmlspecialchars($aPopover["content"]) . "\" ";
|
||||
}
|
||||
|
||||
if($this->option("refreshonchange") === TRUE) {
|
||||
$onchange = " onchange=\"document.getElementsByTagName('form')[0].submit();\" ";
|
||||
}
|
||||
|
||||
$sHtml =<<<HTML
|
||||
<div class="control-group{$groupclass}">
|
||||
<label class="control-label" for="{$prop}">{$label}</label>
|
||||
<div class="controls">
|
||||
<input type="checkbox" class="input-xlarge{$inputclass}" id="{$prop}" name="data[{$prop}]" value="1"{$checked}{$disabled}{$popover}{$onchange}/>
|
||||
{$helpblock}
|
||||
</div>
|
||||
</div>
|
||||
HTML;
|
||||
return $sHtml . $this->renderWitness();
|
||||
}
|
||||
}
|
|
@ -1,104 +0,0 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://formal.codr.fr
|
||||
#
|
||||
# This script is part of the Formal project. The Formal
|
||||
# project is free software; you can redistribute it
|
||||
# and/or modify it under the terms of the GNU General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2 of the License, or (at your option) any later version.
|
||||
#
|
||||
# The GNU General Public License can be found at
|
||||
# http://www.gnu.org/copyleft/gpl.html.
|
||||
#
|
||||
# This script is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# This copyright notice MUST APPEAR in all copies of the script!
|
||||
#################################################################
|
||||
|
||||
namespace Formal\Element;
|
||||
|
||||
class Listbox extends \Formal\Element {
|
||||
public function render() {
|
||||
|
||||
$disabled = "";
|
||||
$inputclass = "";
|
||||
$groupclass = "";
|
||||
$placeholder = "";
|
||||
|
||||
$value = $this->value();
|
||||
$label = $this->option("label");
|
||||
$prop = $this->option("prop");
|
||||
$helpblock = "";
|
||||
$popover = "";
|
||||
|
||||
if($this->option("readonly") === TRUE) {
|
||||
$inputclass .= " disabled";
|
||||
$disabled = " disabled";
|
||||
}
|
||||
|
||||
if($this->option("error") === TRUE) {
|
||||
$groupclass .= " error";
|
||||
}
|
||||
|
||||
$aOptions = $this->option("options");
|
||||
if(!is_array($aOptions)) {
|
||||
throw new \Exception("\Formal\Element\Listbox->render(): 'options' has to be an array.");
|
||||
}
|
||||
|
||||
if(($sHelp = trim($this->option("help"))) !== "") {
|
||||
$helpblock = "<p class=\"help-block\">" . $sHelp . "</p>";
|
||||
}
|
||||
|
||||
if(($aPopover = $this->option("popover")) !== "") {
|
||||
$inputclass .= " popover-focus ";
|
||||
$popover = " title=\"" . htmlspecialchars($aPopover["title"]) . "\" ";
|
||||
$popover .= " data-content=\"" . htmlspecialchars($aPopover["content"]) . "\" ";
|
||||
}
|
||||
|
||||
$clientvalue = htmlspecialchars($value);
|
||||
|
||||
$aRenderedOptions = array();
|
||||
|
||||
if(\Flake\Util\Tools::arrayIsSeq($aOptions)) {
|
||||
# Array is sequential
|
||||
reset($aOptions);
|
||||
foreach($aOptions as $sOptionValue) {
|
||||
$selected = ($sOptionValue === $value) ? " selected=\"selected\"" : "";
|
||||
$aRenderedOptions[] = "<option" . $selected . ">" . htmlspecialchars($sOptionValue) . "</option>";
|
||||
}
|
||||
} else {
|
||||
# Array is associative
|
||||
reset($aOptions);
|
||||
foreach($aOptions as $sOptionValue => $sOptionCaption) {
|
||||
$selected = ($sOptionValue === $value) ? " selected=\"selected\"" : "";
|
||||
$aRenderedOptions[] = "<option value=\"" . htmlspecialchars($sOptionValue) . "\"" . $selected . ">" . htmlspecialchars($sOptionCaption) . "</option>";
|
||||
}
|
||||
}
|
||||
|
||||
reset($aRenderedOptions);
|
||||
$sRenderedOptions = implode("\n", $aRenderedOptions);
|
||||
unset($aRenderedOptions);
|
||||
|
||||
$sHtml =<<<HTML
|
||||
<div class="control-group{$groupclass}">
|
||||
<label class="control-label" for="{$prop}">{$label}</label>
|
||||
<div class="controls">
|
||||
<select class="{$inputclass}" id="{$prop}" name="data[{$prop}]"{$disabled}{$popover}>
|
||||
{$sRenderedOptions}
|
||||
</select>
|
||||
{$helpblock}
|
||||
</div>
|
||||
</div>
|
||||
HTML;
|
||||
return $sHtml . $this->renderWitness();
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://formal.codr.fr
|
||||
#
|
||||
# This script is part of the Formal project. The Formal
|
||||
# project is free software; you can redistribute it
|
||||
# and/or modify it under the terms of the GNU General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2 of the License, or (at your option) any later version.
|
||||
#
|
||||
# The GNU General Public License can be found at
|
||||
# http://www.gnu.org/copyleft/gpl.html.
|
||||
#
|
||||
# This script is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# This copyright notice MUST APPEAR in all copies of the script!
|
||||
#################################################################
|
||||
|
||||
namespace Formal\Element;
|
||||
|
||||
class Password extends \Formal\Element\Text {
|
||||
|
||||
protected function inputtype() {
|
||||
return "password";
|
||||
}
|
||||
}
|
|
@ -1,101 +0,0 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://formal.codr.fr
|
||||
#
|
||||
# This script is part of the Formal project. The Formal
|
||||
# project is free software; you can redistribute it
|
||||
# and/or modify it under the terms of the GNU General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2 of the License, or (at your option) any later version.
|
||||
#
|
||||
# The GNU General Public License can be found at
|
||||
# http://www.gnu.org/copyleft/gpl.html.
|
||||
#
|
||||
# This script is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# This copyright notice MUST APPEAR in all copies of the script!
|
||||
#################################################################
|
||||
|
||||
namespace Formal\Element;
|
||||
|
||||
class Text extends \Formal\Element {
|
||||
|
||||
protected function inputtype() {
|
||||
return "text";
|
||||
}
|
||||
|
||||
public function render() {
|
||||
$disabled = "";
|
||||
$inputclass = "";
|
||||
$groupclass = "";
|
||||
$placeholder = "";
|
||||
|
||||
$value = $this->value();
|
||||
$label = $this->option("label");
|
||||
$prop = $this->option("prop");
|
||||
$placeholder = "";
|
||||
$helpblock = "";
|
||||
$popover = "";
|
||||
|
||||
if($this->option("readonly") === TRUE) {
|
||||
$inputclass .= " disabled";
|
||||
$disabled = " disabled";
|
||||
}
|
||||
|
||||
if($this->option("error") === TRUE) {
|
||||
$groupclass .= " error";
|
||||
}
|
||||
|
||||
if(trim($this->option("class")) !== "") {
|
||||
$groupclass .= " " . $this->option("class");
|
||||
}
|
||||
|
||||
if(trim($this->option("inputclass")) !== "") {
|
||||
$inputclass = $this->option("inputclass");
|
||||
}
|
||||
|
||||
if(($sPlaceHolder = trim($this->option("placeholder"))) !== "") {
|
||||
$placeholder = " placeholder=\"" . htmlspecialchars($sPlaceHolder) . "\" ";
|
||||
}
|
||||
|
||||
$clientvalue = htmlspecialchars($value);
|
||||
|
||||
$sInputType = $this->inputtype();
|
||||
|
||||
if(($sHelp = trim($this->option("help"))) !== "") {
|
||||
$helpblock = "<p class=\"help-block\">" . $sHelp . "</p>";
|
||||
}
|
||||
|
||||
if(($aPopover = $this->option("popover")) !== "") {
|
||||
|
||||
if(array_key_exists("position", $aPopover)) {
|
||||
$sPosition = $aPopover["position"];
|
||||
$inputclass .= " popover-focus-" . $sPosition;
|
||||
} else {
|
||||
$inputclass .= " popover-focus ";
|
||||
}
|
||||
|
||||
$popover = " title=\"" . htmlspecialchars($aPopover["title"]) . "\" ";
|
||||
$popover .= " data-content=\"" . htmlspecialchars($aPopover["content"]) . "\" ";
|
||||
}
|
||||
|
||||
$sHtml =<<<HTML
|
||||
<div class="control-group{$groupclass}">
|
||||
<label class="control-label" for="{$prop}">{$label}</label>
|
||||
<div class="controls">
|
||||
<input type="{$sInputType}" class="{$inputclass}" id="{$prop}" name="data[{$prop}]" value="{$clientvalue}"{$disabled}{$placeholder}{$popover}/>
|
||||
{$helpblock}
|
||||
</div>
|
||||
</div>
|
||||
HTML;
|
||||
return $sHtml . $this->renderWitness();
|
||||
}
|
||||
}
|
|
@ -1,415 +0,0 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://formal.codr.fr
|
||||
#
|
||||
# This script is part of the Formal project. The Formal
|
||||
# project is free software; you can redistribute it
|
||||
# and/or modify it under the terms of the GNU General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2 of the License, or (at your option) any later version.
|
||||
#
|
||||
# The GNU General Public License can be found at
|
||||
# http://www.gnu.org/copyleft/gpl.html.
|
||||
#
|
||||
# This script is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# This copyright notice MUST APPEAR in all copies of the script!
|
||||
#################################################################
|
||||
|
||||
namespace Formal;
|
||||
|
||||
class Form {
|
||||
|
||||
protected $sModelClass = "";
|
||||
protected $aOptions = array(
|
||||
"action" => "",
|
||||
"close" => TRUE,
|
||||
"closeurl" => "",
|
||||
"hook.validation" => FALSE,
|
||||
"hook.morphology" => FALSE,
|
||||
);
|
||||
protected $oModelInstance = null;
|
||||
protected $oElements = null;
|
||||
protected $aErrors = array();
|
||||
protected $bPersisted = null; # TRUE when form has persisted; available only after execute
|
||||
|
||||
protected $sDisplayTitle = ""; # Displayed form title; generated in setModelInstance()
|
||||
protected $sDisplayMessage = ""; # Displayed confirm message; generated in execute()
|
||||
|
||||
protected $oMorpho = 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) {
|
||||
if(array_key_exists($sName, $this->aOptions)) {
|
||||
return $this->aOptions[$sName];
|
||||
}
|
||||
|
||||
throw new \Exception("\Formal\Form->option(): Option '" . htmlspecialchars($sName) . "' not found.");
|
||||
}
|
||||
|
||||
public function setOption($sName, $sValue) {
|
||||
$this->aOptions[$sName] = $sValue;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function options() {
|
||||
$aOptions = $this->aOptions;
|
||||
return $aOptions;
|
||||
}
|
||||
|
||||
public function getMorpho() {
|
||||
if(!is_null($this->oMorpho)) {
|
||||
return $this->oMorpho;
|
||||
}
|
||||
|
||||
$this->oMorpho = $this->modelInstance()->formMorphologyForThisModelInstance();
|
||||
|
||||
# Calling validation hook if defined
|
||||
if(($aHook = $this->option("hook.morphology")) !== FALSE) {
|
||||
call_user_func($aHook, $this, $this->oMorpho);
|
||||
}
|
||||
|
||||
return $this->oMorpho;
|
||||
}
|
||||
|
||||
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->modelInstance()->get(
|
||||
$oElement->option("prop")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
# Displayed form title is generated depending on modelInstance floatingness
|
||||
|
||||
if($this->floatingModelInstance()) {
|
||||
$this->sDisplayTitle = "Creating new<i class=" . $this->modelInstance()->mediumicon() . "></i><strong>" . $this->modelInstance()->humanName() . "</strong>";
|
||||
} else {
|
||||
# This is changed if form is persisted, after persistance, to reflect possible change in model instance label
|
||||
$this->sDisplayTitle = "Editing " . $this->modelInstance()->humanName() . "<i class=" . $this->modelInstance()->mediumicon() . "></i><strong>" . $this->modelInstance()->label() . "</strong>";
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function modelInstance() {
|
||||
return $this->oModelInstance;
|
||||
}
|
||||
|
||||
public function floatingModelInstance() {
|
||||
return $this->modelInstance()->floating();
|
||||
}
|
||||
|
||||
public function execute() {
|
||||
# Obtaining morphology from model object
|
||||
$oMorpho = $this->getMorpho();
|
||||
|
||||
$this->aErrors = array();
|
||||
$oMorpho->elements()->reset();
|
||||
foreach($oMorpho->elements() 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
|
||||
if($oElement->posted()) {
|
||||
|
||||
$sPostValue = $this->postValue($sPropName);
|
||||
$oElement->setValue($sPostValue);
|
||||
|
||||
$sValue = $oElement->value();
|
||||
|
||||
$this->modelInstance()->set(
|
||||
$sPropName,
|
||||
$sValue
|
||||
);
|
||||
} else {
|
||||
$oElement->setValue(
|
||||
$this->modelInstance()->get(
|
||||
$sPropName
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$oMorpho->elements()->reset();
|
||||
foreach($oMorpho->elements() as $oElement) {
|
||||
$aValidation = $oElement->optionArray("validation");
|
||||
if(empty($aValidation)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$sValue = $oElement->value();
|
||||
|
||||
foreach($aValidation as $sValidation) {
|
||||
|
||||
# If element is readonly, skip process
|
||||
if($oElement->option("readonly")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$sParam = FALSE;
|
||||
if(strpos($sValidation, ":") !== FALSE) {
|
||||
$sValidation = strtok($sValidation, ":");
|
||||
$sParam = strtok(":");
|
||||
}
|
||||
|
||||
$sMethod = "validate" . ucfirst(strtolower($sValidation));
|
||||
if(!method_exists($this, $sMethod)) {
|
||||
throw new \Exception("\Formal\Form::execute(): no validation method for '" . htmlspecialchars($sValidation) . "'");
|
||||
}
|
||||
|
||||
if($sParam === FALSE) {
|
||||
$mValid = $this->$sMethod($sValue, $oMorpho, $oElement);
|
||||
} else {
|
||||
$mValid = $this->$sMethod($sValue, $oMorpho, $oElement, $sParam);
|
||||
}
|
||||
|
||||
if($mValid !== TRUE) {
|
||||
$this->declareError($oElement, $mValid);
|
||||
break; # one error per element per submit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Calling validation hook if defined
|
||||
if(($aHook = $this->option("hook.validation")) !== FALSE) {
|
||||
call_user_func($aHook, $this, $oMorpho);
|
||||
}
|
||||
|
||||
if(empty($this->aErrors)) {
|
||||
|
||||
# Model object is persisted
|
||||
# Last chance to generate a confirm message corresponding to what *was* submitted ("Creating", instead of "Editing")
|
||||
|
||||
if($this->floatingModelInstance()) {
|
||||
$this->sDisplayMessage = \Formal\Core\Message::notice(
|
||||
$this->modelInstance()->humanName() . " <i class='" . $this->modelInstance()->icon() . "'></i> <strong>" . $this->modelInstance()->label() . "</strong> has been created.",
|
||||
"",
|
||||
FALSE
|
||||
);
|
||||
$bWasFloating = TRUE;
|
||||
} else {
|
||||
$bWasFloating = FALSE;
|
||||
$this->sDisplayMessage = \Formal\Core\Message::notice(
|
||||
"Changes on <i class='" . $this->modelInstance()->icon() . "'></i> <strong>" . $this->modelInstance()->label() . "</strong> have been saved.",
|
||||
FALSE, # No title
|
||||
FALSE # No close button
|
||||
);
|
||||
}
|
||||
|
||||
$this->modelInstance()->persist();
|
||||
if($bWasFloating === FALSE) {
|
||||
# Title is generated now, as submitted data might have changed the model instance label
|
||||
$this->sDisplayTitle = "Editing " . $this->modelInstance()->humanName() . "<i class=" . $this->modelInstance()->mediumicon() . "></i><strong>" . $this->modelInstance()->label() . "</strong>";
|
||||
}
|
||||
$this->bPersisted = TRUE;
|
||||
} else {
|
||||
$this->bPersisted = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
# public, as it may be called from a hook
|
||||
public function declareError(\Formal\Element $oElement, $sMessage = "") {
|
||||
$this->aErrors[] = array(
|
||||
"element" => $oElement,
|
||||
"message" => $sMessage,
|
||||
);
|
||||
|
||||
$oElement->setOption("error", TRUE);
|
||||
}
|
||||
|
||||
public function persisted() {
|
||||
if($this->submitted()) {
|
||||
if(is_null($this->bPersisted)) {
|
||||
throw new \Exception("\Formal\Form->persisted(): information is not available yet. This method may only be called after execute()");
|
||||
}
|
||||
|
||||
return $this->bPersisted;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
public function validateRequired($sValue, \Formal\Form\Morphology $oMorpho, \Formal\Element $oElement) {
|
||||
if(trim($sValue) !== "") {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return "<strong>" . $oElement->option("label") . "</strong> is required.";
|
||||
}
|
||||
|
||||
public function validateEmail($sValue, \Formal\Form\Morphology $oMorpho, \Formal\Element $oElement) {
|
||||
if(\Flake\Util\Tools::validEmail($sValue)) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return "<strong>" . $oElement->option("label") . "</strong> should be an email.";
|
||||
}
|
||||
|
||||
public function validateSameas($sValue, \Formal\Form\Morphology $oMorpho, \Formal\Element $oElement, $sReferencePropName) {
|
||||
$sReferenceValue = $oMorpho->element($sReferencePropName)->value();
|
||||
if($sValue === $sReferenceValue) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return "<strong>" . $oElement->option("label") . "</strong> does not match " . $oMorpho->element($sReferencePropName)->option("label") . ".";
|
||||
}
|
||||
|
||||
public function validateUnique($sValue, \Formal\Form\Morphology $oMorpho, \Formal\Element $oElement) {
|
||||
$oModelInstance = $this->modelInstance();
|
||||
|
||||
$oRequest = $oModelInstance->getBaseRequester()->addClauseEquals(
|
||||
$oElement->option("prop"),
|
||||
$sValue
|
||||
);
|
||||
|
||||
if(!$oModelInstance->floating()) {
|
||||
# checking id only if model instance is not floating
|
||||
$oRequest->addClauseNotEquals(
|
||||
$oModelInstance::PRIMARYKEY,
|
||||
$oModelInstance->get(
|
||||
$oModelInstance::PRIMARYKEY
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$oColl = $oRequest->execute();
|
||||
|
||||
if($oColl->count() > 0) {
|
||||
return "<strong>" . $oElement->option("label") . "</strong> has to be unique. Given value is not available.";
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
public function validateTokenid($sValue, \Formal\Form\Morphology $oMorpho, \Formal\Element $oElement) {
|
||||
if(!preg_match("/^[a-z0-9\-]+$/", $sValue)) {
|
||||
return "<strong>" . $oElement->option("label") . "</strong> is not valid. Allowed characters are digits, lowercase letters and the dash symbol '-'.";
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
public function postValue($sPropName) {
|
||||
$aData = \Flake\Util\Tools::POST("data");
|
||||
|
||||
if(is_array($aData) && array_key_exists($sPropName, $aData)) {
|
||||
return $aData[$sPropName];
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public function render() {
|
||||
$aHtml = array();
|
||||
|
||||
$oMorpho = $this->getMorpho();
|
||||
|
||||
$oMorpho->elements()->reset();
|
||||
foreach($oMorpho->elements() as $oElement) {
|
||||
|
||||
# Setting current prop value for element
|
||||
# Set on empty (just created) FormMorphology
|
||||
# And obtained from Model instance
|
||||
|
||||
$oElement->setValue(
|
||||
$this->modelInstance()->get(
|
||||
$oElement->option("prop")
|
||||
)
|
||||
);
|
||||
|
||||
$aHtml[] = $oElement->render();
|
||||
}
|
||||
|
||||
$elements = implode("\n", $aHtml);
|
||||
$sModelClass = $this->sModelClass;
|
||||
|
||||
######################################################
|
||||
# Displaying messages
|
||||
######################################################
|
||||
|
||||
if($this->submitted()) {
|
||||
|
||||
# There were errors detected during execute()
|
||||
# Error messages are displayed
|
||||
|
||||
if(!empty($this->aErrors)) {
|
||||
$this->sDisplayMessage = "";
|
||||
$aMessages = array();
|
||||
reset($this->aErrors);
|
||||
foreach($this->aErrors as $aError) {
|
||||
if(trim($aError["message"]) === "") {
|
||||
continue;
|
||||
}
|
||||
|
||||
$aMessages[] = $aError["message"];
|
||||
}
|
||||
|
||||
$this->sDisplayMessage = \Formal\Core\Message::error(
|
||||
implode("<br />", $aMessages),
|
||||
"Validation error"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$sSubmittedFlagName = $this->submitSignatureName();
|
||||
if($this->option("close") === TRUE) {
|
||||
$sCloseUrl = $this->option("closeurl");
|
||||
$sCloseButton = '<a class="btn" href="' . $sCloseUrl . '">Close</a>';
|
||||
} else {
|
||||
$sCloseButton = "";
|
||||
}
|
||||
|
||||
$sActionUrl = $this->option("action");
|
||||
|
||||
$sHtml =<<<HTML
|
||||
<form class="form-horizontal" action="{$sActionUrl}" method="post" enctype="multipart/formdata">
|
||||
<input type="hidden" name="{$sSubmittedFlagName}" value="1" />
|
||||
<fieldset>
|
||||
<legend style="line-height: 40px;">{$this->sDisplayTitle}</legend>
|
||||
{$this->sDisplayMessage}
|
||||
{$elements}
|
||||
<div class="form-actions">
|
||||
<button type="submit" class="btn btn-primary">Save changes</button>
|
||||
{$sCloseButton}
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
HTML;
|
||||
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
protected function submitSignatureName() {
|
||||
return str_replace('\\', '_', $this->sModelClass . "::submitted");
|
||||
}
|
||||
|
||||
public function submitted() {
|
||||
return intval(\Flake\Util\Tools::POST($this->submitSignatureName())) === 1;
|
||||
}
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://formal.codr.fr
|
||||
#
|
||||
# This script is part of the Formal project. The Formal
|
||||
# project is free software; you can redistribute it
|
||||
# and/or modify it under the terms of the GNU General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2 of the License, or (at your option) any later version.
|
||||
#
|
||||
# The GNU General Public License can be found at
|
||||
# http://www.gnu.org/copyleft/gpl.html.
|
||||
#
|
||||
# This script is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# This copyright notice MUST APPEAR in all copies of the script!
|
||||
#################################################################
|
||||
|
||||
namespace Formal\Form;
|
||||
|
||||
class Morphology {
|
||||
|
||||
protected $oElements = null;
|
||||
|
||||
public function __construct() {
|
||||
$this->oElements = new \Flake\Core\CollectionTyped("\Formal\Element");
|
||||
}
|
||||
|
||||
public function add(\Formal\Element $oElement) {
|
||||
$this->oElements->push($oElement);
|
||||
}
|
||||
|
||||
protected function keyForPropName($sPropName) {
|
||||
$aKeys = $this->oElements->keys();
|
||||
reset($aKeys);
|
||||
foreach($aKeys as $sKey) {
|
||||
$oElement = $this->oElements->getForKey($sKey);
|
||||
|
||||
if($oElement->option("prop") === $sPropName) {
|
||||
return $sKey;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
public function &element($sPropName) {
|
||||
if(($sKey = $this->keyForPropName($sPropName)) === FALSE) {
|
||||
throw new \Exception("\Formal\Form\Morphology->element(): Element prop='" . $sPropName . "' not found");
|
||||
}
|
||||
|
||||
$oElement = $this->oElements->getForKey($sKey);
|
||||
return $oElement;
|
||||
}
|
||||
|
||||
public function remove($sPropName) {
|
||||
if(($sKey = $this->keyForPropName($sPropName)) === FALSE) {
|
||||
throw new \Exception("\Formal\Form\Morphology->element(): Element prop='" . $sPropName . "' not found");
|
||||
}
|
||||
|
||||
$this->oElements->remove($sKey);
|
||||
}
|
||||
|
||||
public function elements() {
|
||||
return $this->oElements;
|
||||
}
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://formal.codr.fr
|
||||
#
|
||||
# This script is part of the Formal project. The Formal
|
||||
# project is free software; you can redistribute it
|
||||
# and/or modify it under the terms of the GNU General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2 of the License, or (at your option) any later version.
|
||||
#
|
||||
# The GNU General Public License can be found at
|
||||
# http://www.gnu.org/copyleft/gpl.html.
|
||||
#
|
||||
# This script is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# This copyright notice MUST APPEAR in all copies of the script!
|
||||
#################################################################
|
||||
|
||||
namespace Formal;
|
||||
|
||||
class Framework extends \Flake\Core\Framework {
|
||||
|
||||
public static function bootstrap() {
|
||||
define("FORMAL_PATH_ROOT", PROJECT_PATH_ROOT . "Core/Frameworks/Formal/");
|
||||
|
||||
require_once(FORMAL_PATH_ROOT . 'Core/ClassLoader.php');
|
||||
\Formal\Core\ClassLoader::register();
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue