Merge branch 'restructuration'
This commit is contained in:
commit
b586d01710
206 changed files with 18009 additions and 8 deletions
6
.gitmodules
vendored
6
.gitmodules
vendored
|
@ -1,7 +1 @@
|
|||
|
||||
[submodule "Core/Frameworks/Formal"]
|
||||
path = Core/Frameworks/Formal
|
||||
url = https://jeromeschneider@github.com/jeromeschneider/Formal.git
|
||||
[submodule "Core/Frameworks/Flake"]
|
||||
path = Core/Frameworks/Flake
|
||||
url = https://jeromeschneider@github.com/jeromeschneider/Flake.git
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
Subproject commit 3679cb4a0dbc808f9200f495a2e1f6a3dd0fe4ca
|
154
Core/Frameworks/Flake/Controller/Cli.php
Normal file
154
Core/Frameworks/Flake/Controller/Cli.php
Normal file
|
@ -0,0 +1,154 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://flake.codr.fr
|
||||
#
|
||||
# This script is part of the Flake project. The Flake
|
||||
# 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 Flake\Controller;
|
||||
|
||||
class Cli extends \Flake\Core\Render\Container {
|
||||
|
||||
function render() {
|
||||
$this->sys_init();
|
||||
$this->init();
|
||||
|
||||
$this->echoFlush($this->notice("process started @" . strftime("%d/%m/%Y %H:%M:%S")));
|
||||
$this->execute();
|
||||
$this->echoFlush($this->notice("process ended @" . strftime("%d/%m/%Y %H:%M:%S")) . "\n\n");
|
||||
}
|
||||
|
||||
function execute() {
|
||||
reset($this->aSequence);
|
||||
while(list($sKey,) = each($this->aSequence)) {
|
||||
$this->aSequence[$sKey]["block"]->execute();
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
var $sLog = "";
|
||||
|
||||
function sys_init() {
|
||||
$this->rawLine("Command line: " . (implode(" ", $_SERVER["argv"])));
|
||||
$this->initArgs();
|
||||
}
|
||||
|
||||
function init() {
|
||||
}
|
||||
|
||||
function initArgs() {
|
||||
$sShortOpts = "";
|
||||
$sShortOpts .= "h"; // help; pas de valeur
|
||||
$sShortOpts .= "w:"; // author; valeur obligatoire
|
||||
|
||||
$aLongOpts = array(
|
||||
"help", // help; pas de valeur
|
||||
"helloworld", // author; pas de valeur
|
||||
);
|
||||
|
||||
$this->aArgs = getopt($sShortOpts, $aLongOpts);
|
||||
}
|
||||
|
||||
function getScriptPath() {
|
||||
return realpath($_SERVER['argv'][0]);
|
||||
}
|
||||
|
||||
function getSyntax() {
|
||||
return $this->getScriptPath();
|
||||
}
|
||||
|
||||
function syntaxError() {
|
||||
$sStr = $this->rawLine("Syntax error.\nUsage: " . $this->getSyntax());
|
||||
die("\n\n" . $sStr . "\n\n");
|
||||
}
|
||||
|
||||
function log($sStr) {
|
||||
$this->sLog .= $sStr;
|
||||
}
|
||||
|
||||
function header($sMsg) {
|
||||
|
||||
$sStr = "\n" . str_repeat("#", 80);
|
||||
$sStr .= "\n" . "#" . str_repeat(" ", 78) . "#";
|
||||
$sStr .= "\n" . "#" . str_pad(strtoupper($sMsg), 78, " ", STR_PAD_BOTH) . "#";
|
||||
$sStr .= "\n" . "#" . str_repeat(" ", 78) . "#";
|
||||
$sStr .= "\n" . str_repeat("#", 80);
|
||||
$sStr .= "\n";
|
||||
|
||||
$this->log($sStr);
|
||||
return $sStr;
|
||||
}
|
||||
|
||||
function subHeader($sMsg) {
|
||||
$sStr = "\n\n# " . str_pad(strtoupper($sMsg) . " ", 78, "-", STR_PAD_RIGHT) . "\n";
|
||||
$this->log($sStr);
|
||||
return $sStr;
|
||||
}
|
||||
|
||||
function subHeader2($sMsg) {
|
||||
$sStr = "\n# # " . str_pad($sMsg . " ", 76, "-", STR_PAD_RIGHT) . "\n";
|
||||
$this->log($sStr);
|
||||
return $sStr;
|
||||
}
|
||||
|
||||
function textLine($sMsg) {
|
||||
$sStr = ". " . $sMsg . "\n";
|
||||
$this->log($sStr);
|
||||
return $sStr;
|
||||
}
|
||||
|
||||
function rawLine($sMsg) {
|
||||
$sStr = $sMsg . "\n";
|
||||
$this->log($sStr);
|
||||
return $sStr;
|
||||
}
|
||||
|
||||
function notice($sMsg) {
|
||||
$sStr = "\n" . str_pad($sMsg, 80, ".", STR_PAD_BOTH) . "\n";
|
||||
$this->log($sStr);
|
||||
return $sStr;
|
||||
}
|
||||
|
||||
function getLog() {
|
||||
return $this->sLog;
|
||||
}
|
||||
|
||||
function file_writeBin($sPath, $sData, $bUTF8 = TRUE) {
|
||||
|
||||
$rFile = fopen($sPath, "wb");
|
||||
|
||||
if($bUTF8 === TRUE) {
|
||||
fputs($rFile, "\xEF\xBB\xBF" . $sData);
|
||||
} else {
|
||||
fputs($rFile, $sData);
|
||||
}
|
||||
|
||||
fclose($rFile);
|
||||
}
|
||||
|
||||
function echoFlush($sString = "") {
|
||||
echo $sString;
|
||||
ob_flush();
|
||||
flush();
|
||||
}
|
||||
}
|
42
Core/Frameworks/Flake/Controller/HtmlBlock.php
Normal file
42
Core/Frameworks/Flake/Controller/HtmlBlock.php
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://flake.codr.fr
|
||||
#
|
||||
# This script is part of the Flake project. The Flake
|
||||
# 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 Flake\Controller;
|
||||
|
||||
class HtmlBlock extends \Flake\Core\Controller {
|
||||
|
||||
function __construct($sHtml) {
|
||||
$this->sHtml = $sHtml;
|
||||
}
|
||||
|
||||
function execute() {
|
||||
|
||||
}
|
||||
|
||||
function render() {
|
||||
return $this->sHtml;
|
||||
}
|
||||
}
|
44
Core/Frameworks/Flake/Controller/HtmlBlockTemplated.php
Normal file
44
Core/Frameworks/Flake/Controller/HtmlBlockTemplated.php
Normal file
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://flake.codr.fr
|
||||
#
|
||||
# This script is part of the Flake project. The Flake
|
||||
# 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 Flake\Controller;
|
||||
|
||||
class HtmlBlockTemplated extends \Flake\Core\Controller {
|
||||
|
||||
function __construct($sTemplatePath, $aMarkers = array()) {
|
||||
$this->sTemplatePath = $sTemplatePath;
|
||||
$this->aMarkers = $aMarkers;
|
||||
}
|
||||
|
||||
function render() {
|
||||
$oTemplate = new \Flake\Core\Template($this->sTemplatePath);
|
||||
$sHtml = $oTemplate->parse(
|
||||
$this->aMarkers
|
||||
);
|
||||
|
||||
return $sHtml;
|
||||
}
|
||||
}
|
123
Core/Frameworks/Flake/Controller/Page.php
Normal file
123
Core/Frameworks/Flake/Controller/Page.php
Normal file
|
@ -0,0 +1,123 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://flake.codr.fr
|
||||
#
|
||||
# This script is part of the Flake project. The Flake
|
||||
# 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 Flake\Controller;
|
||||
|
||||
class Page extends \Flake\Core\Render\Container {
|
||||
|
||||
protected $sTitle = "";
|
||||
protected $sMetaKeywords = "";
|
||||
protected $sMetaDescription = "";
|
||||
protected $sTemplatePath = "";
|
||||
|
||||
public function __construct($sTemplatePath) {
|
||||
$this->sTemplatePath = $sTemplatePath;
|
||||
}
|
||||
|
||||
public function setTitle($sTitle) {
|
||||
$this->sTitle = $sTitle;
|
||||
}
|
||||
|
||||
public function setMetaKeywords($sKeywords) {
|
||||
$this->sMetaKeywords = $sKeywords;
|
||||
}
|
||||
|
||||
public function setMetaDescription($sDescription) {
|
||||
$this->sMetaDescription = $sDescription;
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
return $this->sTitle;
|
||||
}
|
||||
|
||||
public function getMetaKeywords() {
|
||||
$sString = str_replace(array("le", "la", "les", "de", "des", "un", "une"), " ", $this->sMetaKeywords);
|
||||
$sString = \Flake\Util\Tools::stringToUrlToken($sString);
|
||||
return implode(", ", explode("-", $sString));
|
||||
}
|
||||
|
||||
public function getMetaDescription() {
|
||||
return $this->sMetaDescription;
|
||||
}
|
||||
|
||||
public function setBaseUrl($sBaseUrl) {
|
||||
$this->sBaseUrl = $sBaseUrl;
|
||||
}
|
||||
|
||||
public function getBaseUrl() {
|
||||
return $this->sBaseUrl;
|
||||
}
|
||||
|
||||
public function injectHTTPHeaders() {
|
||||
header("Content-Type: text/html; charset=UTF-8");
|
||||
}
|
||||
|
||||
public function render() {
|
||||
$this->execute();
|
||||
|
||||
$aRenderedBlocks = $this->renderBlocks();
|
||||
$aRenderedBlocks["pagetitle"] = $this->getTitle();
|
||||
$aRenderedBlocks["pagemetakeywords"] = $this->getMetaKeywords();
|
||||
$aRenderedBlocks["pagemetadescription"] = $this->getMetaDescription();
|
||||
$aRenderedBlocks["baseurl"] = $this->getBaseUrl();
|
||||
|
||||
$oTemplate = new \Flake\Core\Template($this->sTemplatePath);
|
||||
$sHtml = $oTemplate->parse(
|
||||
$aRenderedBlocks
|
||||
);
|
||||
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
public function addCss($sCssAbsPath) {
|
||||
|
||||
if(\Flake\Util\Frameworks::enabled("LessPHP")) {
|
||||
$sCompiledPath = PATH_buildcss;
|
||||
$sFileName = basename($sCssAbsPath);
|
||||
|
||||
$sCompiledFilePath = $sCompiledPath . \Flake\Util\Tools::shortMD5($sFileName) . "_" . $sFileName;
|
||||
|
||||
if(substr(strtolower($sCompiledFilePath), -4) !== ".css") {
|
||||
$sCompiledFilePath .= ".css";
|
||||
}
|
||||
|
||||
if(!file_exists($sCompiledPath)) {
|
||||
@mkdir($sCompiledPath);
|
||||
if(!file_exists($sCompiledPath)) {
|
||||
die("Page: Cannot create " . $sCompiledPath);
|
||||
}
|
||||
}
|
||||
|
||||
\Frameworks\LessPHP\Delegate::compileCss($sCssAbsPath, $sCompiledFilePath);
|
||||
$sCssUrl = \Flake\Util\Tools::serverToRelativeWebPath($sCompiledFilePath);
|
||||
} else {
|
||||
$sCssUrl = \Flake\Util\Tools::serverToRelativeWebPath($sCssAbsPath);
|
||||
}
|
||||
|
||||
$sHtml = "<link rel=\"stylesheet\" type=\"text/css\" href=\"" . $sCssUrl . "\" media=\"all\"/>";
|
||||
$this->zone("head")->addBlock(new \Flake\Controller\HtmlBlock($sHtml));
|
||||
}
|
||||
}
|
68
Core/Frameworks/Flake/Controller/Rpc.php
Normal file
68
Core/Frameworks/Flake/Controller/Rpc.php
Normal file
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://flake.codr.fr
|
||||
#
|
||||
# This script is part of the Flake project. The Flake
|
||||
# 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 Flake\Controller;
|
||||
|
||||
class Rpc extends \Flake\Core\Render\Container {
|
||||
|
||||
public function initializeContext() {
|
||||
$this->injectHTTPHeaders();
|
||||
$GLOBALS["POSTCONNECTIONSERVICES"] = array();
|
||||
}
|
||||
|
||||
public function injectHTTPHeaders() {
|
||||
ob_start();
|
||||
|
||||
header("Access-Control-Allow-Origin: *"); # To allow cross domain AJAX response
|
||||
header("Access-Control-Allow-Credentials: true"); # To allow cross domain cookies
|
||||
header("Content-Type: application/json; charset=UTF-8");
|
||||
|
||||
# Needed to cut client off when needed
|
||||
header("Connection: close\r\n");
|
||||
ignore_user_abort(TRUE);
|
||||
|
||||
}
|
||||
|
||||
public function P3PAllowCrossDomainCookies() {
|
||||
# This tells IE6+ to accept passing cookies allong when establishing a XHR connection to read.codr.fr
|
||||
header('P3P: CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"');
|
||||
}
|
||||
|
||||
public function sendResponseCutClientAndRunPostConnectionTasks() {
|
||||
header("Content-Length: " . ob_get_length());
|
||||
ob_end_flush();
|
||||
flush();
|
||||
|
||||
reset($GLOBALS["POSTCONNECTIONSERVICES"]);
|
||||
|
||||
# If post-connection services are registered, process
|
||||
foreach($GLOBALS["POSTCONNECTIONSERVICES"] as $service) {
|
||||
$service->execute();
|
||||
}
|
||||
|
||||
session_write_close();
|
||||
}
|
||||
}
|
85
Core/Frameworks/Flake/Core/ClassLoader.php
Normal file
85
Core/Frameworks/Flake/Core/ClassLoader.php
Normal file
|
@ -0,0 +1,85 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://flake.codr.fr
|
||||
#
|
||||
# This script is part of the Flake project. The Flake
|
||||
# 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 Flake\Core;
|
||||
|
||||
class ClassLoader {
|
||||
|
||||
public static function register() {
|
||||
return spl_autoload_register(array(__CLASS__, 'loadClass'));
|
||||
}
|
||||
|
||||
public static function loadClass($sFullClassName) {
|
||||
|
||||
$sClassPath = FALSE;
|
||||
|
||||
$aParts = explode("\\", $sFullClassName);
|
||||
if(count($aParts) === 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
# Extracting the Radical
|
||||
$sRadical = $aParts[0];
|
||||
|
||||
if(in_array($sRadical, array("Flake", "Specific", "Frameworks"))) {
|
||||
|
||||
if($sRadical === "Flake") {
|
||||
$sRootPath = FLAKE_PATH_ROOT;
|
||||
} elseif($sRadical === "Specific") {
|
||||
$sRootPath = FLAKE_PATH_SPECIFIC;
|
||||
} else {
|
||||
$sRootPath = PROJECT_PATH_FRAMEWORKS;
|
||||
}
|
||||
|
||||
# Stripping radical
|
||||
array_shift($aParts);
|
||||
|
||||
# Classname is the last part
|
||||
$sClassName = array_pop($aParts);
|
||||
|
||||
# Path to class
|
||||
$sClassPath = $sRootPath . implode("/", $aParts) . "/" . $sClassName . ".php";
|
||||
|
||||
} elseif(count($aParts) > 1) {
|
||||
if($aParts[1] === "Framework") {
|
||||
# It must be a Flake Framework
|
||||
$sClassPath = PROJECT_PATH_FRAMEWORKS . $sRadical . "/Framework.php";
|
||||
}
|
||||
}
|
||||
|
||||
if($sClassPath === FALSE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(file_exists($sClassPath) && is_readable($sClassPath)) {
|
||||
require_once($sClassPath);
|
||||
} else {
|
||||
echo '<h1>PHP Autoload Error. Cannot find ' . $sFullClassName . ' in ' . $sClassPath . '</h1>';
|
||||
echo "<pre>" . print_r(debug_backtrace(), TRUE) . "</pre>";
|
||||
die();
|
||||
}
|
||||
}
|
||||
}
|
214
Core/Frameworks/Flake/Core/Collection.php
Normal file
214
Core/Frameworks/Flake/Core/Collection.php
Normal file
|
@ -0,0 +1,214 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://flake.codr.fr
|
||||
#
|
||||
# This script is part of the Flake project. The Flake
|
||||
# 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 Flake\Core;
|
||||
|
||||
class Collection extends \Flake\Core\FLObject implements \Iterator {
|
||||
protected $aCollection = array();
|
||||
protected $aMeta = array();
|
||||
|
||||
public function current() {
|
||||
return current($this->aCollection);
|
||||
}
|
||||
|
||||
public function key() {
|
||||
return key($this->aCollection);
|
||||
}
|
||||
|
||||
public function next() {
|
||||
return next($this->aCollection);
|
||||
}
|
||||
|
||||
public function rewind() {
|
||||
$this->reset();
|
||||
}
|
||||
|
||||
public function valid() {
|
||||
$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");
|
||||
}
|
||||
|
||||
$oRes = $this->aCollection[$sKey];
|
||||
return $oRes;
|
||||
}
|
||||
|
||||
public function &each() {
|
||||
list($key, $val) = each($this->aCollection);
|
||||
return $val;
|
||||
}
|
||||
|
||||
public function reset() {
|
||||
reset($this->aCollection);
|
||||
}
|
||||
|
||||
public function prev() {
|
||||
return prev($this->aCollection);
|
||||
}
|
||||
|
||||
public function count() {
|
||||
return count($this->aCollection);
|
||||
}
|
||||
|
||||
public function keys() {
|
||||
return array_keys($this->aCollection);
|
||||
}
|
||||
|
||||
public function isEmpty() {
|
||||
return $this->count() === 0;
|
||||
}
|
||||
|
||||
public function isAtFirst() {
|
||||
return $this->key() === array_shift($this->keys());
|
||||
}
|
||||
|
||||
public function isAtLast() {
|
||||
return $this->key() === array_pop($this->keys());
|
||||
}
|
||||
|
||||
public function push(&$mMixed) {
|
||||
array_push($this->aCollection, $mMixed);
|
||||
}
|
||||
|
||||
public function flush() {
|
||||
unset($this->aCollection);
|
||||
$this->aCollection = array();
|
||||
}
|
||||
|
||||
public function &first() {
|
||||
if(!$this->isEmpty()) {
|
||||
$aKeys = $this->keys();
|
||||
return $this->aCollection[array_shift($aKeys)];
|
||||
}
|
||||
|
||||
$var = null; # two lines instead of one
|
||||
return $var; # as PHP needs a variable to return by ref
|
||||
}
|
||||
|
||||
public function &last() {
|
||||
if(!$this->isEmpty()) {
|
||||
$aKeys = $this->keys();
|
||||
return $this->aCollection[array_pop($aKeys)];
|
||||
}
|
||||
|
||||
$var = null;
|
||||
return $var;
|
||||
}
|
||||
|
||||
public function toArray() {
|
||||
return $this->aCollection;
|
||||
}
|
||||
|
||||
public static function fromArray($aData) {
|
||||
$oColl = new \Flake\Core\Collection();
|
||||
reset($aData);
|
||||
foreach($aData as $mData) {
|
||||
$oColl->push($mData);
|
||||
}
|
||||
|
||||
return $oColl;
|
||||
}
|
||||
|
||||
# Create a new collection like this one
|
||||
# This abstraction is useful because of CollectionTyped
|
||||
protected function newCollectionLikeThisOne() {
|
||||
$oCollection = new \Flake\Core\Collection(); # two lines instead of one
|
||||
return $oCollection; # as PHP needs a variable to return by ref
|
||||
}
|
||||
|
||||
public function map($sFunc) {
|
||||
$aData = $this->toArray();
|
||||
$oNewColl = $this->fromArray(array_map($sFunc, $aData));
|
||||
return $oNewColl;
|
||||
}
|
||||
|
||||
public function walk($sFunc, $aParams=array()) {
|
||||
$aData = $this->toArray();
|
||||
$oNewColl = $this->fromArray(array_walk($aData, $sFunc, $aParams));
|
||||
return $oNewColl;
|
||||
}
|
||||
|
||||
public function remove($sKey) {
|
||||
$aKeys = $this->keys();
|
||||
if(!in_array($sKey, $aKeys)) {
|
||||
throw new \Exception("\Flake\Core\Collection->remove(): key '" . $sKey . "' not found in Collection");
|
||||
}
|
||||
|
||||
unset($this->aCollection[$sKey]);
|
||||
$this->aCollection = array_values($this->aCollection);
|
||||
}
|
||||
|
||||
public function &__call($sName, $aArguments) {
|
||||
if(
|
||||
strlen($sName) > 7 &&
|
||||
$sName{0} === "s" &&
|
||||
$sName{1} === "e" &&
|
||||
$sName{2} === "t" &&
|
||||
$sName{3} === "M" &&
|
||||
$sName{4} === "e" &&
|
||||
$sName{5} === "t" &&
|
||||
$sName{6} === "a"
|
||||
) {
|
||||
$sKey = strtolower(substr($sName, 7, 1)) . substr($sName, 8);
|
||||
$mValue =& $aArguments[0];
|
||||
|
||||
if(is_null($mValue)) {
|
||||
if(array_key_exists($sKey, $this->aMeta)) {
|
||||
unset($this->aMeta[$sKey]);
|
||||
}
|
||||
} else {
|
||||
$this->aMeta[$sKey] =& $mValue;
|
||||
}
|
||||
|
||||
$res = NULL;
|
||||
return $res; # To avoid 'Notice: Only variable references should be returned by reference'
|
||||
|
||||
} elseif(
|
||||
strlen($sName) > 7 &&
|
||||
$sName{0} === "g" &&
|
||||
$sName{1} === "e" &&
|
||||
$sName{2} === "t" &&
|
||||
$sName{3} === "M" &&
|
||||
$sName{4} === "e" &&
|
||||
$sName{5} === "t" &&
|
||||
$sName{6} === "a"
|
||||
) {
|
||||
$sKey = strtolower(substr($sName, 7, 1)) . substr($sName, 8);
|
||||
if(array_key_exists($sKey, $this->aMeta)) {
|
||||
return $this->aMeta[$sKey];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
throw new \Exception("Method " . $sName . "() not found on " . get_class($this));
|
||||
}
|
||||
}
|
||||
}
|
51
Core/Frameworks/Flake/Core/CollectionTyped.php
Normal file
51
Core/Frameworks/Flake/Core/CollectionTyped.php
Normal file
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://flake.codr.fr
|
||||
#
|
||||
# This script is part of the Flake project. The Flake
|
||||
# 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 Flake\Core;
|
||||
|
||||
class CollectionTyped extends \Flake\Core\Collection {
|
||||
|
||||
protected $sTypeClassOrProtocol;
|
||||
|
||||
public function __construct($sTypeClassOrProtocol) {
|
||||
$this->sTypeClassOrProtocol = $sTypeClassOrProtocol;
|
||||
$this->setMetaType($this->sTypeClassOrProtocol);
|
||||
}
|
||||
|
||||
public function push(&$mMixed) {
|
||||
if(!\Flake\Util\Tools::is_a($mMixed, $this->sTypeClassOrProtocol)) {
|
||||
throw new \Exception("\Flake\Core\CollectionTyped<" . $this->sTypeClassOrProtocol . ">: Given object is not correctly typed.");
|
||||
}
|
||||
|
||||
parent::push($mMixed);
|
||||
}
|
||||
|
||||
# Create a new collection like this one
|
||||
public function newCollectionLikeThisOne() {
|
||||
$oCollection = new \Flake\Core\CollectionTyped($this->sTypeClassOrProtocol);
|
||||
return $oCollection;
|
||||
}
|
||||
}
|
56
Core/Frameworks/Flake/Core/Controller.php
Normal file
56
Core/Frameworks/Flake/Core/Controller.php
Normal file
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://flake.codr.fr
|
||||
#
|
||||
# This script is part of the Flake project. The Flake
|
||||
# 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 Flake\Core;
|
||||
|
||||
abstract class Controller extends \Flake\Core\FLObject {
|
||||
|
||||
protected $aParams = array();
|
||||
|
||||
public function __construct($aParams = array()) {
|
||||
$this->aParams = $aParams;
|
||||
}
|
||||
|
||||
public function getParams() {
|
||||
return $this->aParams;
|
||||
}
|
||||
|
||||
public static function link(/*[$sParam, $sParam2, ...]*/) {
|
||||
return static::buildRoute();
|
||||
}
|
||||
|
||||
public static function buildRoute($aParams = array()) {
|
||||
# TODO: il faut remplacer le mécanisme basé sur un nombre variable de paramètres en un mécanisme basé sur un seul paramètre "tableau"
|
||||
#$aParams = func_get_args();
|
||||
$sController = "\\" . get_called_class();
|
||||
#array_unshift($aParams, $sController); # Injecting current controller as first param
|
||||
#return call_user_func_array($GLOBALS["ROUTER"] . "::buildRouteForController", $aParams);
|
||||
return $GLOBALS["ROUTER"]::buildRouteForController($sController, $aParams);
|
||||
}
|
||||
|
||||
public abstract function execute();
|
||||
public abstract function render();
|
||||
}
|
130
Core/Frameworks/Flake/Core/DOM/HTMLElement.php
Normal file
130
Core/Frameworks/Flake/Core/DOM/HTMLElement.php
Normal file
|
@ -0,0 +1,130 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://bootstrap.codr.fr
|
||||
#
|
||||
# This script is part of the CodrBootstrap project. The CodrBootstrap 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 Flake\Core\DOM;
|
||||
|
||||
class HTMLElement extends \DOMElement {
|
||||
public function getInnerText() {
|
||||
return $this->nodeValue;
|
||||
}
|
||||
|
||||
public function getOuterHTML() {
|
||||
return $this->ownerDocument->saveHTML($this);
|
||||
}
|
||||
|
||||
public function getNormalizedInnerText() {
|
||||
return $this->normalizeWhiteSpace($this->getInnerText());
|
||||
}
|
||||
|
||||
public function getNormalizedOuterHTML() {
|
||||
return $this->normalizeWhitespace($this->getOuterHTML());
|
||||
}
|
||||
|
||||
protected function normalizeWhitespace($sText) {
|
||||
$sText = str_replace(array("\t", "\r\n", "\n"), ' ', $sText);
|
||||
|
||||
# using multiple str_replace has proven to be twice as fast that regexp on big strings
|
||||
$iCount = 0;
|
||||
do {
|
||||
$sText = str_replace(' ', ' ', $sText, $iCount);
|
||||
} while($iCount > 0);
|
||||
|
||||
return trim($sText);
|
||||
}
|
||||
|
||||
public function setInnerHTML($sHtml) {
|
||||
// first, empty the element
|
||||
for ($x=$this->childNodes->length-1; $x>=0; $x--) {
|
||||
$this->removeChild($this->childNodes->item($x));
|
||||
}
|
||||
// $value holds our new inner HTML
|
||||
if ($sHtml != '') {
|
||||
$f = $this->ownerDocument->createDocumentFragment();
|
||||
// appendXML() expects well-formed markup (XHTML)
|
||||
$result = @$f->appendXML($sHtml); // @ to suppress PHP warnings
|
||||
if ($result) {
|
||||
if ($f->hasChildNodes()) $this->appendChild($f);
|
||||
} else {
|
||||
// $value is probably ill-formed
|
||||
$f = new \DOMDocument();
|
||||
$sHtml = mb_convert_encoding($sHtml, 'HTML-ENTITIES', 'UTF-8');
|
||||
// Using <htmlfragment> will generate a warning, but so will bad HTML
|
||||
// (and by this point, bad HTML is what we've got).
|
||||
// We use it (and suppress the warning) because an HTML fragment will
|
||||
// be wrapped around <html><body> tags which we don't really want to keep.
|
||||
// Note: despite the warning, if loadHTML succeeds it will return true.
|
||||
$result = @$f->loadHTML('<htmlfragment>'.$sHtml.'</htmlfragment>');
|
||||
if ($result) {
|
||||
$import = $f->getElementsByTagName('htmlfragment')->item(0);
|
||||
foreach ($import->childNodes as $child) {
|
||||
$importedNode = $this->ownerDocument->importNode($child, true);
|
||||
$this->appendChild($importedNode);
|
||||
}
|
||||
} else {
|
||||
// oh well, we tried, we really did. :(
|
||||
// this element is now empty
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getInnerHTML() {
|
||||
$sHtml = '';
|
||||
$iNodes = $this->childNodes->length;
|
||||
for($i = 0; $i < $iNodes; $i++) {
|
||||
$oItem = $this->childNodes->item($i);
|
||||
$sHtml .= $oItem->ownerDocument->saveHTML($oItem);
|
||||
}
|
||||
|
||||
return $sHtml;
|
||||
}
|
||||
|
||||
public function isDOMText() {
|
||||
return $this->nodeType === XML_TEXT_NODE;
|
||||
}
|
||||
|
||||
public function getSiblingPosition() {
|
||||
$iPos = 0;
|
||||
$oNode = $this;
|
||||
|
||||
while(!is_null($oNode->previousSibling)) {
|
||||
$oNode = $oNode->previousSibling;
|
||||
$iPos++;
|
||||
}
|
||||
|
||||
return $iPos;
|
||||
}
|
||||
|
||||
public function getTreePosition() {
|
||||
# Tree position is number 100^level + sibling offset
|
||||
$iLevel = substr_count($this->getNodePath(), "/") - 2; # -1 to align on 0, and -1 to compensate for /document
|
||||
if($iLevel === 0) {
|
||||
return $this->getSiblingPosition();
|
||||
} else {
|
||||
return pow(10, $iLevel) + $this->getSiblingPosition();
|
||||
}
|
||||
}
|
||||
}
|
208
Core/Frameworks/Flake/Core/Database.php
Normal file
208
Core/Frameworks/Flake/Core/Database.php
Normal file
|
@ -0,0 +1,208 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://flake.codr.fr
|
||||
#
|
||||
# This script is part of the Flake project. The Flake
|
||||
# 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 Flake\Core;
|
||||
|
||||
abstract class Database extends \Flake\Core\FLObject {
|
||||
|
||||
/* common stuff */
|
||||
|
||||
protected function messageAndDie($sMessage) {
|
||||
$sError = "<h2>" . get_class($this) . ": " . $sMessage . "</h2>";
|
||||
die($sError);
|
||||
}
|
||||
|
||||
public function exec_INSERTquery($table,$fields_values,$no_quote_fields=FALSE) {
|
||||
return $this->query($this->INSERTquery($table,$fields_values,$no_quote_fields));
|
||||
}
|
||||
|
||||
public function INSERTquery($table,$fields_values,$no_quote_fields=FALSE) {
|
||||
|
||||
// Table and fieldnames should be "SQL-injection-safe" when supplied to this function (contrary to values in the arrays which may be insecure).
|
||||
if (is_array($fields_values) && count($fields_values)) {
|
||||
|
||||
// quote and escape values
|
||||
$fields_values = $this->fullQuoteArray($fields_values,$table,$no_quote_fields);
|
||||
|
||||
// Build query:
|
||||
$query = 'INSERT INTO '.$table.'
|
||||
(
|
||||
'.implode(',
|
||||
',array_keys($fields_values)).'
|
||||
) VALUES (
|
||||
'.implode(',
|
||||
',$fields_values).'
|
||||
)';
|
||||
|
||||
// Return query:
|
||||
if ($this->debugOutput || $this->store_lastBuiltQuery) $this->debug_lastBuiltQuery = $query;
|
||||
return $query;
|
||||
}
|
||||
}
|
||||
|
||||
public function exec_UPDATEquery($table,$where,$fields_values,$no_quote_fields=FALSE) {
|
||||
return $this->query($this->UPDATEquery($table,$where,$fields_values,$no_quote_fields));
|
||||
}
|
||||
|
||||
public function UPDATEquery($table,$where,$fields_values,$no_quote_fields=FALSE) {
|
||||
|
||||
// Table and fieldnames should be "SQL-injection-safe" when supplied to this function (contrary to values in the arrays which may be insecure).
|
||||
if (is_string($where)) {
|
||||
if (is_array($fields_values) && count($fields_values)) {
|
||||
|
||||
// quote and escape values
|
||||
$nArr = $this->fullQuoteArray($fields_values,$table,$no_quote_fields);
|
||||
|
||||
$fields = array();
|
||||
foreach ($nArr as $k => $v) {
|
||||
$fields[] = $k.'='.$v;
|
||||
}
|
||||
|
||||
// Build query:
|
||||
$query = 'UPDATE '.$table.'
|
||||
SET
|
||||
'.implode(',
|
||||
',$fields).
|
||||
(strlen($where)>0 ? '
|
||||
WHERE
|
||||
'.$where : '');
|
||||
|
||||
// Return query:
|
||||
if ($this->debugOutput || $this->store_lastBuiltQuery) $this->debug_lastBuiltQuery = $query;
|
||||
return $query;
|
||||
}
|
||||
} else {
|
||||
die('<strong>Fatal Error:</strong> "Where" clause argument for UPDATE query was not a string in $this->UPDATEquery() !');
|
||||
}
|
||||
}
|
||||
|
||||
public function exec_DELETEquery($table,$where) {
|
||||
return $this->query($this->DELETEquery($table,$where));
|
||||
}
|
||||
|
||||
public function DELETEquery($table,$where) {
|
||||
if (is_string($where)) {
|
||||
|
||||
// Table and fieldnames should be "SQL-injection-safe" when supplied to this function
|
||||
$query = 'DELETE FROM '.$table.
|
||||
(strlen($where)>0 ? '
|
||||
WHERE
|
||||
'.$where : '');
|
||||
|
||||
if ($this->debugOutput || $this->store_lastBuiltQuery) $this->debug_lastBuiltQuery = $query;
|
||||
return $query;
|
||||
} else {
|
||||
die('<strong>Fatal Error:</strong> "Where" clause argument for DELETE query was not a string in $this->DELETEquery() !');
|
||||
}
|
||||
}
|
||||
|
||||
public function exec_SELECTquery($select_fields,$from_table,$where_clause,$groupBy='',$orderBy='',$limit='') {
|
||||
return $this->query($this->SELECTquery($select_fields,$from_table,$where_clause,$groupBy,$orderBy,$limit));
|
||||
}
|
||||
|
||||
public function SELECTquery($select_fields,$from_table,$where_clause,$groupBy='',$orderBy='',$limit='') {
|
||||
|
||||
// Table and fieldnames should be "SQL-injection-safe" when supplied to this function
|
||||
// Build basic query:
|
||||
$query = 'SELECT '.$select_fields.'
|
||||
FROM '.$from_table.
|
||||
(strlen($where_clause)>0 ? '
|
||||
WHERE
|
||||
'.$where_clause : '');
|
||||
|
||||
// Group by:
|
||||
if (strlen($groupBy)>0) {
|
||||
$query.= '
|
||||
GROUP BY '.$groupBy;
|
||||
}
|
||||
// Order by:
|
||||
if (strlen($orderBy)>0) {
|
||||
$query.= '
|
||||
ORDER BY '.$orderBy;
|
||||
}
|
||||
// Group by:
|
||||
if (strlen($limit)>0) {
|
||||
$query.= '
|
||||
LIMIT '.$limit;
|
||||
}
|
||||
|
||||
// Return query:
|
||||
if ($this->debugOutput || $this->store_lastBuiltQuery) $this->debug_lastBuiltQuery = $query;
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function fullQuote($str, $table) {
|
||||
return '\''.$this->quote($str, $table).'\'';
|
||||
}
|
||||
|
||||
public function fullQuoteArray($arr, $table, $noQuote=FALSE) {
|
||||
if (is_string($noQuote)) {
|
||||
$noQuote = explode(',',$noQuote);
|
||||
} elseif (!is_array($noQuote)) { // sanity check
|
||||
$noQuote = FALSE;
|
||||
}
|
||||
|
||||
foreach($arr as $k => $v) {
|
||||
if ($noQuote===FALSE || !in_array($k,$noQuote)) {
|
||||
$arr[$k] = $this->fullQuote($v, $table);
|
||||
}
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
|
||||
/* Should be abstract, but we provide a body anyway as PDO abstracts these methods for us */
|
||||
|
||||
public function query($sSql) {
|
||||
if(($stmt = $this->oDb->query($sSql)) === FALSE) {
|
||||
$sMessage = print_r($this->oDb->errorInfo(), TRUE);
|
||||
throw new \Exception("SQL ERROR in: '" . $sSql . "'; Message: " . $sMessage);
|
||||
}
|
||||
|
||||
return new \Flake\Core\Database\Statement($stmt);
|
||||
}
|
||||
|
||||
public function lastInsertId() {
|
||||
return $this->oDb->lastInsertId();
|
||||
}
|
||||
|
||||
public function quote($str) {
|
||||
return substr($this->oDb->quote($str), 1, -1); # stripping first and last quote
|
||||
}
|
||||
|
||||
public function getPDO() {
|
||||
return $this->oDb;
|
||||
}
|
||||
|
||||
public function close() {
|
||||
$this->oDb = null;
|
||||
}
|
||||
|
||||
public function __destruct() {
|
||||
$this->close();
|
||||
}
|
||||
|
||||
public abstract function tables();
|
||||
}
|
67
Core/Frameworks/Flake/Core/Database/Mysql.php
Normal file
67
Core/Frameworks/Flake/Core/Database/Mysql.php
Normal file
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://flake.codr.fr
|
||||
#
|
||||
# This script is part of the Flake project. The Flake
|
||||
# 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 Flake\Core\Database;
|
||||
|
||||
class Mysql extends \Flake\Core\Database {
|
||||
|
||||
protected $oDb = FALSE; // current DB link
|
||||
protected $debugOutput = FALSE;
|
||||
protected $store_lastBuiltQuery = TRUE;
|
||||
protected $debug_lastBuiltQuery = "";
|
||||
protected $sHost = "";
|
||||
protected $sDbName = "";
|
||||
protected $sUsername = "";
|
||||
protected $sPassword = "";
|
||||
|
||||
public function __construct($sHost, $sDbName, $sUsername, $sPassword) {
|
||||
$this->sHost = $sHost;
|
||||
$this->sDbName = $sDbName;
|
||||
$this->sUsername = $sUsername;
|
||||
$this->sPassword = $sPassword;
|
||||
|
||||
$this->oDb = new \PDO(
|
||||
'mysql:host=' . $this->sHost . ';dbname=' . $this->sDbName,
|
||||
$this->sUsername,
|
||||
$this->sPassword
|
||||
);
|
||||
}
|
||||
|
||||
public function tables() {
|
||||
$aTables = array();
|
||||
|
||||
$sSql = "SHOW TABLES FROM " . $this->sDbName;
|
||||
$oStmt = $this->query($sSql);
|
||||
|
||||
while(($aRs = $oStmt->fetch()) !== FALSE) {
|
||||
$aTables[] = array_shift($aRs);
|
||||
}
|
||||
|
||||
asort($aTables);
|
||||
reset($aTables);
|
||||
return $aTables;
|
||||
}
|
||||
}
|
60
Core/Frameworks/Flake/Core/Database/Sqlite.php
Normal file
60
Core/Frameworks/Flake/Core/Database/Sqlite.php
Normal file
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://flake.codr.fr
|
||||
#
|
||||
# This script is part of the Flake project. The Flake
|
||||
# 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 Flake\Core\Database;
|
||||
|
||||
class Sqlite extends \Flake\Core\Database {
|
||||
|
||||
protected $oDb = FALSE; // current DB link
|
||||
protected $debugOutput = FALSE;
|
||||
protected $store_lastBuiltQuery = TRUE;
|
||||
protected $debug_lastBuiltQuery = "";
|
||||
protected $sDbPath = "";
|
||||
|
||||
public function __construct($sDbPath) {
|
||||
$this->sDbPath = $sDbPath;
|
||||
$this->oDb = new \PDO('sqlite:' . $this->sDbPath);
|
||||
}
|
||||
|
||||
# Taken from http://dev.kohanaframework.org/issues/2985
|
||||
public function tables() {
|
||||
$aTables = array();
|
||||
|
||||
# Find all user level table names
|
||||
$oStmt = $this->query('SELECT name '
|
||||
.'FROM sqlite_master '
|
||||
.'WHERE type=\'table\' AND name NOT LIKE \'sqlite_%\' '
|
||||
.'ORDER BY name');
|
||||
|
||||
while(($aRs = $oStmt->fetch()) !== FALSE) {
|
||||
// Get the table name from the results
|
||||
$aTables[] = array_shift($aRs);
|
||||
}
|
||||
|
||||
reset($aTables);
|
||||
return $aTables;
|
||||
}
|
||||
}
|
43
Core/Frameworks/Flake/Core/Database/Statement.php
Normal file
43
Core/Frameworks/Flake/Core/Database/Statement.php
Normal file
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://flake.codr.fr
|
||||
#
|
||||
# This script is part of the Flake project. The Flake
|
||||
# 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 Flake\Core\Database;
|
||||
|
||||
class Statement extends \Flake\Core\FLObject {
|
||||
protected $stmt = null;
|
||||
|
||||
public function __construct($stmt) {
|
||||
$this->stmt = $stmt;
|
||||
}
|
||||
|
||||
public function fetch() {
|
||||
if($this->stmt !== FALSE) {
|
||||
return $this->stmt->fetch(\PDO::FETCH_ASSOC, \PDO::FETCH_ORI_FIRST);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
62
Core/Frameworks/Flake/Core/Datastructure/Chain.php
Normal file
62
Core/Frameworks/Flake/Core/Datastructure/Chain.php
Normal file
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://flake.codr.fr
|
||||
#
|
||||
# This script is part of the Flake project. The Flake
|
||||
# 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 Flake\Core\Datastructure;
|
||||
|
||||
class Chain extends \SplDoublyLinkedList {
|
||||
|
||||
public function push(\Flake\Core\Datastructure\Chainable $value) {
|
||||
$value->chain($this, $this->count());
|
||||
parent::push($value);
|
||||
}
|
||||
|
||||
public function offsetUnset($offset) {
|
||||
throw new \Exception("Cannot delete Chainable in Chain");
|
||||
}
|
||||
|
||||
public function &first() {
|
||||
$oRes = $this->bottom();
|
||||
return $oRes;
|
||||
}
|
||||
|
||||
public function &last() {
|
||||
$oRes = $this->top();
|
||||
return $oRes;
|
||||
}
|
||||
|
||||
public function reset() {
|
||||
reset($this);
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
ob_start();
|
||||
var_dump($this);
|
||||
$sDump = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
return "<pre>" . htmlspecialchars($sDump) . "</pre>";
|
||||
}
|
||||
}
|
110
Core/Frameworks/Flake/Core/Datastructure/ChainLink.php
Normal file
110
Core/Frameworks/Flake/Core/Datastructure/ChainLink.php
Normal file
|
@ -0,0 +1,110 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://flake.codr.fr
|
||||
#
|
||||
# This script is part of the Flake project. The Flake
|
||||
# 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 Flake\Core\Datastructure;
|
||||
|
||||
abstract class ChainLink implements \Flake\Core\Datastructure\Chainable {
|
||||
protected $__container = null;
|
||||
protected $__key = null;
|
||||
|
||||
public function chain(Chain $container, $key) {
|
||||
$this->__container = $container;
|
||||
$this->__key = $key;
|
||||
}
|
||||
|
||||
public function offsetSet($offset,$value) {
|
||||
if(is_null($this->__container)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->__container->offsetSet($offset, $value);
|
||||
}
|
||||
|
||||
public function offsetExists($offset) {
|
||||
if(is_null($this->__container)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return $this->__container->offsetExists($offset);
|
||||
}
|
||||
|
||||
public function offsetUnset($offset) {
|
||||
if(is_null($this->__container)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->__container->offsetUnset($offset);
|
||||
}
|
||||
|
||||
public function &offsetGet($offset) {
|
||||
if(is_null($this->__container)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$oRes = $this->__container->offsetGet($offset);
|
||||
return $oRes;
|
||||
}
|
||||
|
||||
public function rewind() {
|
||||
$this->__container->rewind();
|
||||
}
|
||||
|
||||
public function current() {
|
||||
return $this->__container->current();
|
||||
}
|
||||
|
||||
public function key() {
|
||||
return $this->__container->key();
|
||||
}
|
||||
|
||||
public function &next() {
|
||||
$oRes = $this->__container->next();
|
||||
return $oRes;
|
||||
}
|
||||
|
||||
public function &prev() {
|
||||
$oPrev = $this->__container->prev();
|
||||
return $oPrev;
|
||||
}
|
||||
|
||||
public function valid() {
|
||||
return $this->__container->valid();
|
||||
}
|
||||
|
||||
public function count() {
|
||||
return $this->__container->count();
|
||||
}
|
||||
|
||||
public function &first() {
|
||||
$oRes = $this->__container->first();
|
||||
return $oRes;
|
||||
}
|
||||
|
||||
public function &last() {
|
||||
$oRes = $this->__container->last();
|
||||
return $oRes;
|
||||
}
|
||||
}
|
38
Core/Frameworks/Flake/Core/Datastructure/Chainable.php
Normal file
38
Core/Frameworks/Flake/Core/Datastructure/Chainable.php
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://flake.codr.fr
|
||||
#
|
||||
# This script is part of the Flake project. The Flake
|
||||
# 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 Flake\Core\Datastructure;
|
||||
|
||||
interface Chainable extends \ArrayAccess, \Iterator, \Countable {
|
||||
|
||||
# public function &next(); # This is already specified by interface Iterator
|
||||
public function &prev();
|
||||
|
||||
public function &first();
|
||||
public function &last();
|
||||
|
||||
public function chain(\Flake\Core\Datastructure\Chain $chain, $key);
|
||||
}
|
42
Core/Frameworks/Flake/Core/FLObject.php
Normal file
42
Core/Frameworks/Flake/Core/FLObject.php
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://flake.codr.fr
|
||||
#
|
||||
# This script is part of the Flake project. The Flake
|
||||
# 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 Flake\Core;
|
||||
|
||||
class FLObject {
|
||||
public function __toString() {
|
||||
ob_start();
|
||||
var_dump($this);
|
||||
$sDump = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
return "<pre>" . htmlspecialchars($sDump) . "</pre>";
|
||||
}
|
||||
|
||||
public function isA($sClassOrProtocolName) {
|
||||
return \Flake\Util\Tools::is_a($this, $sClassOrProtocolName);
|
||||
}
|
||||
}
|
31
Core/Frameworks/Flake/Core/Framework.php
Normal file
31
Core/Frameworks/Flake/Core/Framework.php
Normal file
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://flake.codr.fr
|
||||
#
|
||||
# This script is part of the Flake project. The Flake
|
||||
# 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 Flake\Core;
|
||||
|
||||
class Framework {
|
||||
|
||||
}
|
106
Core/Frameworks/Flake/Core/Model.php
Normal file
106
Core/Frameworks/Flake/Core/Model.php
Normal file
|
@ -0,0 +1,106 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://flake.codr.fr
|
||||
#
|
||||
# This script is part of the Flake project. The Flake
|
||||
# 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 Flake\Core;
|
||||
|
||||
abstract class Model extends \Flake\Core\FLObject {
|
||||
protected $aData = array();
|
||||
|
||||
protected function getData() {
|
||||
reset($this->aData);
|
||||
return $this->aData;
|
||||
}
|
||||
|
||||
public function __get($sPropName) {
|
||||
return $this->get($sPropName);
|
||||
}
|
||||
|
||||
public function __isset($name) {
|
||||
if(array_key_exists($name, $this->aData)) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
public function get($sPropName) {
|
||||
if(array_key_exists($sPropName, $this->aData)) {
|
||||
return $this->aData[$sPropName];
|
||||
}
|
||||
|
||||
throw new \Exception("\Flake\Core\Model->get(): property " . htmlspecialchars($sPropName) . " does not exist on " . get_class($this));
|
||||
}
|
||||
|
||||
public function set($sPropName, $sPropValue) {
|
||||
if(array_key_exists($sPropName, $this->aData)) {
|
||||
$this->aData[$sPropName] = $sPropValue;
|
||||
return $this;
|
||||
}
|
||||
|
||||
throw new \Exception("\Flake\Core\Model->set(): property " . htmlspecialchars($sPropName) . " does not exist on " . get_class($this));
|
||||
}
|
||||
|
||||
public function label() {
|
||||
return $this->get($this::LABELFIELD);
|
||||
}
|
||||
|
||||
public static function icon() {
|
||||
return "icon-book";
|
||||
}
|
||||
|
||||
public static function mediumicon() {
|
||||
return "glyph-book";
|
||||
}
|
||||
|
||||
public static function bigicon() {
|
||||
return "glyph2x-book";
|
||||
}
|
||||
|
||||
public static function humanName() {
|
||||
$aRes = explode("\\", get_called_class());
|
||||
return array_pop($aRes);
|
||||
}
|
||||
|
||||
public function floating() {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
public function formForThisModelInstance($options = array()) {
|
||||
$sClass = get_class($this);
|
||||
$oForm = new \Formal\Form($sClass, $options);
|
||||
$oForm->setModelInstance($this);
|
||||
|
||||
return $oForm;
|
||||
}
|
||||
|
||||
public function formMorphologyForThisModelInstance() {
|
||||
throw new \Exception(get_class($this) . ": No form morphology provided for Model.");
|
||||
}
|
||||
|
||||
public abstract function persist();
|
||||
|
||||
public abstract function destroy();
|
||||
}
|
119
Core/Frameworks/Flake/Core/Model/Db.php
Normal file
119
Core/Frameworks/Flake/Core/Model/Db.php
Normal file
|
@ -0,0 +1,119 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://flake.codr.fr
|
||||
#
|
||||
# This script is part of the Flake project. The Flake
|
||||
# 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 Flake\Core\Model;
|
||||
|
||||
abstract class Db extends \Flake\Core\Model {
|
||||
|
||||
protected $bFloating = TRUE;
|
||||
|
||||
public function __construct($sPrimary = FALSE) {
|
||||
if($sPrimary === FALSE) {
|
||||
# Object will be floating
|
||||
$this->initFloating();
|
||||
$this->bFloating = TRUE;
|
||||
} else {
|
||||
$this->initByPrimary($sPrimary);
|
||||
$this->bFloating = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
public static function &getBaseRequester() {
|
||||
$oRequester = new \Flake\Core\Requester\Sql(get_called_class());
|
||||
$oRequester->setDataTable(self::getDataTable());
|
||||
|
||||
return $oRequester;
|
||||
}
|
||||
|
||||
public static function &getByRequest(\FS\Core\Requester\Sql $oRequester) {
|
||||
// renvoie une collection de la classe du modèle courant (this)
|
||||
return $oRequester->execute();
|
||||
}
|
||||
|
||||
public static function getDataTable() {
|
||||
$sClass = get_called_class();
|
||||
return $sClass::DATATABLE;
|
||||
}
|
||||
|
||||
public static function getPrimaryKey() {
|
||||
$sClass = get_called_class();
|
||||
return $sClass::PRIMARYKEY;
|
||||
}
|
||||
|
||||
public function getPrimary() {
|
||||
return $this->get(self::getPrimaryKey());
|
||||
}
|
||||
|
||||
protected function initByPrimary($sPrimary) {
|
||||
|
||||
$rSql = $GLOBALS["DB"]->exec_SELECTquery(
|
||||
"*",
|
||||
self::getDataTable(),
|
||||
self::getPrimaryKey() . "='" . $GLOBALS["DB"]->quote($sPrimary) . "'"
|
||||
);
|
||||
|
||||
if(($aRs = $rSql->fetch()) === FALSE) {
|
||||
throw new \Exception("\Flake\Core\Model '" . htmlspecialchars($sPrimary) . "' not found for model " . get_class($this));
|
||||
}
|
||||
|
||||
reset($aRs);
|
||||
$this->aData = $aRs;
|
||||
}
|
||||
|
||||
public function persist() {
|
||||
if($this->floating()) {
|
||||
$GLOBALS["DB"]->exec_INSERTquery(
|
||||
self::getDataTable(),
|
||||
$this->getData()
|
||||
);
|
||||
|
||||
$sPrimary = $GLOBALS["DB"]->lastInsertId();
|
||||
$this->initByPrimary($sPrimary);
|
||||
$this->bFloating = FALSE;
|
||||
} else {
|
||||
$GLOBALS["DB"]->exec_UPDATEquery(
|
||||
self::getDataTable(),
|
||||
self::getPrimaryKey() . "='" . $GLOBALS["DB"]->quote($this->getPrimary()) . "'",
|
||||
$this->getData()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function destroy() {
|
||||
$GLOBALS["DB"]->exec_DELETEquery(
|
||||
self::getDataTable(),
|
||||
self::getPrimaryKey() . "='" . $GLOBALS["DB"]->quote($this->getPrimary()) . "'"
|
||||
);
|
||||
}
|
||||
|
||||
protected function initFloating() {
|
||||
# nothing; object will be blank
|
||||
}
|
||||
|
||||
public function floating() {
|
||||
return $this->bFloating;
|
||||
}
|
||||
}
|
36
Core/Frameworks/Flake/Core/Model/NoDb.php
Normal file
36
Core/Frameworks/Flake/Core/Model/NoDb.php
Normal file
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://flake.codr.fr
|
||||
#
|
||||
# This script is part of the Flake project. The Flake
|
||||
# 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 Flake\Core\Model;
|
||||
|
||||
abstract class NoDb extends \Flake\Core\Model {
|
||||
|
||||
public function __construct($aData = FALSE) {
|
||||
if($aData !== FALSE) {
|
||||
$this->aData = $aData;
|
||||
}
|
||||
}
|
||||
}
|
39
Core/Frameworks/Flake/Core/PostConnectionService.php
Normal file
39
Core/Frameworks/Flake/Core/PostConnectionService.php
Normal file
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://flake.codr.fr
|
||||
#
|
||||
# This script is part of the Flake project. The Flake
|
||||
# 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 Flake\Core;
|
||||
|
||||
abstract class PostConnectionService extends \Flake\Core\FLObject {
|
||||
|
||||
public function __construct($aParams = array()) {
|
||||
$this->aParams = $aParams;
|
||||
}
|
||||
|
||||
public function execute() {
|
||||
sleep(10);
|
||||
mail("mail@jeromeschneider.fr", "Hello", "je suis la");
|
||||
}
|
||||
}
|
82
Core/Frameworks/Flake/Core/Render/Container.php
Normal file
82
Core/Frameworks/Flake/Core/Render/Container.php
Normal file
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://flake.codr.fr
|
||||
#
|
||||
# This script is part of the Flake project. The Flake
|
||||
# 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 Flake\Core\Render;
|
||||
|
||||
abstract class Container extends \Flake\Core\Controller {
|
||||
|
||||
var $aSequence = array();
|
||||
var $aBlocks = array();
|
||||
var $aRendu = array();
|
||||
var $aZones = array();
|
||||
|
||||
function addBlock(&$oBlock, $sZone = "_DEFAULT_") {
|
||||
$aTemp = array(
|
||||
"block" => &$oBlock,
|
||||
"rendu" => "",
|
||||
);
|
||||
$this->aSequence[] =& $aTemp;
|
||||
$this->aBlocks[$sZone][] =& $aTemp["rendu"];
|
||||
}
|
||||
|
||||
function &zone($sZone) {
|
||||
if(!array_key_exists($sZone, $this->aZones)) {
|
||||
$this->aZones[$sZone] = new \Flake\Core\Render\Zone($this, $sZone);
|
||||
}
|
||||
|
||||
return $this->aZones[$sZone];
|
||||
}
|
||||
|
||||
public function render() {
|
||||
$this->execute();
|
||||
$aRenderedBlocks = $this->renderBlocks();
|
||||
return implode("", $aRenderedBlocks);
|
||||
}
|
||||
|
||||
public function execute() {
|
||||
reset($this->aSequence);
|
||||
while(list($sKey,) = each($this->aSequence)) {
|
||||
$this->aSequence[$sKey]["block"]->execute();
|
||||
}
|
||||
}
|
||||
|
||||
protected function renderBlocks() {
|
||||
$aHtml = array();
|
||||
reset($this->aSequence);
|
||||
while(list($sKey,) = each($this->aSequence)) {
|
||||
$this->aSequence[$sKey]["rendu"] = $this->aSequence[$sKey]["block"]->render();
|
||||
}
|
||||
|
||||
$aHtml = array();
|
||||
reset($this->aBlocks);
|
||||
while(list($sZone,) = each($this->aBlocks)) {
|
||||
$aHtml[$sZone] = implode("", $this->aBlocks[$sZone]);
|
||||
}
|
||||
|
||||
reset($aHtml);
|
||||
return $aHtml;
|
||||
}
|
||||
}
|
41
Core/Frameworks/Flake/Core/Render/Zone.php
Normal file
41
Core/Frameworks/Flake/Core/Render/Zone.php
Normal file
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://flake.codr.fr
|
||||
#
|
||||
# This script is part of the Flake project. The Flake
|
||||
# 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 Flake\Core\Render;
|
||||
|
||||
class Zone extends \Flake\Core\FLObject {
|
||||
function __construct(&$oZonableObject, $sZone) {
|
||||
$this->oZonableObject =& $oZonableObject;
|
||||
$this->sZone = $sZone;
|
||||
}
|
||||
|
||||
function addBlock(&$oBlock) {
|
||||
$this->oZonableObject->addBlock(
|
||||
$oBlock,
|
||||
$this->sZone
|
||||
);
|
||||
}
|
||||
}
|
65
Core/Frameworks/Flake/Core/Requester.php
Normal file
65
Core/Frameworks/Flake/Core/Requester.php
Normal file
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://flake.codr.fr
|
||||
#
|
||||
# This script is part of the Flake project. The Flake
|
||||
# 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 Flake\Core;
|
||||
|
||||
abstract class Requester extends \Flake\Core\FLObject {
|
||||
public function __construct($sModelClass) {
|
||||
$this->sModelClass = $sModelClass;
|
||||
}
|
||||
|
||||
protected function addClause($sField, $sValue) {
|
||||
$this->addClauseEquals($sField, $sValue);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function limit($iStart, $iNumber = FALSE) {
|
||||
if($iNumber !== FALSE) {
|
||||
return $this->setLimitStart($iStart)->setLimitNumber($iLimitNumber);
|
||||
}
|
||||
|
||||
return $this->setLimitStart($iStart);
|
||||
}
|
||||
|
||||
public function orderBy($sOrderField, $sOrderDirection = "ASC") {
|
||||
$this->sOrderField = $sOrderField;
|
||||
$this->sOrderDirection = $sOrderDirection;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setLimitStart($iLimitStart) {
|
||||
$this->iLimitStart = $iLimitStart;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setLimitNumber($iLimitNumber) {
|
||||
$this->iLimitNumber = $iLimitNumber;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public abstract function execute();
|
||||
public abstract function count();
|
||||
}
|
208
Core/Frameworks/Flake/Core/Requester/Sql.php
Normal file
208
Core/Frameworks/Flake/Core/Requester/Sql.php
Normal file
|
@ -0,0 +1,208 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://flake.codr.fr
|
||||
#
|
||||
# This script is part of the Flake project. The Flake
|
||||
# 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 Flake\Core\Requester;
|
||||
|
||||
class Sql extends \Flake\Core\Requester {
|
||||
|
||||
protected $sDataTable = "";
|
||||
protected $aClauses = array();
|
||||
protected $sModelClass = "";
|
||||
protected $sOrderField = "";
|
||||
protected $sOrderDirection = "ASC";
|
||||
protected $iLimitStart = FALSE;
|
||||
protected $iLimitNumber = FALSE;
|
||||
protected $bHasBeenExecuted = FALSE;
|
||||
|
||||
public function setDataTable($sDataTable) {
|
||||
$this->sDataTable = $sDataTable;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addClauseEquals($sField, $sValue) {
|
||||
$sWrap = "{field}='{value}'";
|
||||
$this->addClauseWrapped($sField, $sValue, $sWrap);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addClauseNotEquals($sField, $sValue) {
|
||||
$sWrap = "{field}!='{value}'";
|
||||
$this->addClauseWrapped($sField, $sValue, $sWrap);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addClauseLike($sField, $sValue) {
|
||||
$sWrap = "{field} LIKE '%{value}%'";
|
||||
$this->addClauseWrapped($sField, $sValue, $sWrap);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addClauseLikeBeginning($sField, $sValue) {
|
||||
$sWrap = "{field} LIKE '{value}%'";
|
||||
$this->addClauseWrapped($sField, $sValue, $sWrap);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addClauseLikeEnd($sField, $sValue) {
|
||||
$sWrap = "{field} LIKE '%{value}'";
|
||||
$this->addClauseWrapped($sField, $sValue, $sWrap);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addClauseNotLike($sField, $sValue) {
|
||||
$sWrap = "{field} NOT LIKE '%{value}%'";
|
||||
$this->addClauseWrapped($sField, $sValue, $sWrap);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addClauseNotLikeBeginning($sField, $sValue) {
|
||||
$sWrap = "{field} NOT LIKE '{value}%'";
|
||||
$this->addClauseWrapped($sField, $sValue, $sWrap);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addClauseNotLikeEnd($sField, $sValue) {
|
||||
$sWrap = "{field} NOT LIKE '%{value}'";
|
||||
$this->addClauseWrapped($sField, $sValue, $sWrap);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addClauseIn($sField, $sValue) {
|
||||
$sWrap = "{field} IN ({value})";
|
||||
$this->addClauseWrapped($sField, $sValue, $sWrap);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addClauseNotIn($sField, $sValue) {
|
||||
$sWrap = "{field} NOT IN ({value})";
|
||||
$this->addClauseWrapped($sField, $sValue, $sWrap);
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function addClauseWrapped($sField, $sValue, $sWrap) {
|
||||
$sValue = $this->escapeSqlValue($sValue);
|
||||
$sClause = str_replace(
|
||||
array(
|
||||
"{field}",
|
||||
"{value}",
|
||||
),
|
||||
array(
|
||||
$sField,
|
||||
$sValue
|
||||
),
|
||||
$sWrap
|
||||
);
|
||||
|
||||
$this->addClauseLiteral($sClause);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addClauseLiteral($sClause) {
|
||||
$this->aClauses[] = $sClause;
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function escapeSqlValue($sValue) {
|
||||
return $GLOBALS["DB"]->quote(
|
||||
$sValue,
|
||||
$this->sDataTable
|
||||
);
|
||||
}
|
||||
|
||||
protected function &reify($aData) {
|
||||
$sTemp = $this->sModelClass;
|
||||
$res = new $sTemp($aData[$sTemp::getPrimaryKey()]);
|
||||
return $res; # To address 'Notice: Only variable references should be returned by reference'
|
||||
}
|
||||
|
||||
public function hasBeenExecuted() {
|
||||
return $this->bHasBeenExecuted;
|
||||
}
|
||||
|
||||
public function getQuery($sFields = "*") {
|
||||
$sWhere = "1=1";
|
||||
$sOrderBy = "";
|
||||
$sLimit = "";
|
||||
|
||||
if(!empty($this->aClauses)) {
|
||||
$sWhere = implode(" AND ", $this->aClauses);
|
||||
}
|
||||
|
||||
if(trim($this->sOrderField) !== "") {
|
||||
$sOrderBy = $this->sOrderField . " " . $this->sOrderDirection;
|
||||
}
|
||||
|
||||
if($this->iLimitStart !== FALSE) {
|
||||
if($this->iLimitNumber !== FALSE) {
|
||||
$sLimit = $this->iLimitStart . ", " . $this->iLimitNumber;
|
||||
} else {
|
||||
$sLimit = $this->iLimitStart;
|
||||
}
|
||||
} elseif($this->iLimitNumber !== FALSE) {
|
||||
$sLimit = "0, " . $this->iLimitNumber;
|
||||
}
|
||||
|
||||
return $GLOBALS["DB"]->SELECTquery(
|
||||
$sFields,
|
||||
$this->sDataTable,
|
||||
$sWhere,
|
||||
"",
|
||||
$sOrderBy,
|
||||
$sLimit
|
||||
);
|
||||
}
|
||||
|
||||
public function getCountQuery() {
|
||||
return $this->getQuery("count(*) as nbitems");
|
||||
}
|
||||
|
||||
public function execute() {
|
||||
$oCollection = new \Flake\Core\CollectionTyped($this->sModelClass);
|
||||
$sSql = $this->getQuery();
|
||||
|
||||
$rSql = $GLOBALS["DB"]->query($sSql);
|
||||
while(($aRs = $rSql->fetch()) !== FALSE) {
|
||||
$oCollection->push(
|
||||
$this->reify($aRs)
|
||||
);
|
||||
}
|
||||
|
||||
$this->bHasBeenExecuted = TRUE;
|
||||
|
||||
return $oCollection;
|
||||
}
|
||||
|
||||
public function count() {
|
||||
$sSql = $this->getCountQuery();
|
||||
|
||||
$rSql = $GLOBALS["DB"]->query($sSql);
|
||||
if(($aRs = $rSql->fetch()) !== FALSE) {
|
||||
return intval($aRs["nbitems"]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
63
Core/Frameworks/Flake/Core/Route.php
Normal file
63
Core/Frameworks/Flake/Core/Route.php
Normal file
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://flake.codr.fr
|
||||
#
|
||||
# This script is part of the Flake project. The Flake
|
||||
# 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 Flake\Core;
|
||||
|
||||
abstract class Route extends \Flake\Core\FLObject {
|
||||
|
||||
# should be abstract, but is not, due to PHP strict standard
|
||||
public static function layout(\Flake\Core\Render\Container &$oRenderContainer) {
|
||||
|
||||
}
|
||||
public static function parametersMap() {
|
||||
return array();
|
||||
}
|
||||
|
||||
# converts raw url params "a/b/c/d"=[a, b, c, d] in route params [a=>b, c=>d]
|
||||
|
||||
public static function getParams() {
|
||||
$aRouteParams = array();
|
||||
|
||||
$aParametersMap = static::parametersMap(); # static to use method as defined in derived class
|
||||
$aURLParams = $GLOBALS["ROUTER"]::getURLParams();
|
||||
|
||||
reset($aParametersMap);
|
||||
foreach($aParametersMap as $sParam => $aMap) {
|
||||
$sURLToken = $sParam;
|
||||
|
||||
if(array_key_exists("urltoken", $aMap)) {
|
||||
$sURLToken = $aMap["urltoken"];
|
||||
}
|
||||
|
||||
if(($iPos = array_search($sURLToken, $aURLParams)) !== FALSE) {
|
||||
$aRouteParams[$sParam] = $aURLParams[($iPos + 1)]; # the value corresponding to this param is the next one in the URL
|
||||
}
|
||||
}
|
||||
|
||||
reset($aRouteParams);
|
||||
return $aRouteParams;
|
||||
}
|
||||
}
|
51
Core/Frameworks/Flake/Core/Template.php
Normal file
51
Core/Frameworks/Flake/Core/Template.php
Normal file
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://flake.codr.fr
|
||||
#
|
||||
# This script is part of the Flake project. The Flake
|
||||
# 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 Flake\Core;
|
||||
|
||||
class Template extends \Flake\Core\FLObject {
|
||||
|
||||
private $sAbsPath = "";
|
||||
private $sHtml = "";
|
||||
|
||||
public function __construct($sAbsPath) {
|
||||
$this->sAbsPath = $sAbsPath;
|
||||
$this->sHtml = $this->getTemplateFile(
|
||||
$this->sAbsPath
|
||||
);
|
||||
}
|
||||
|
||||
private function getTemplateFile($sAbsPath) {
|
||||
return file_get_contents($sAbsPath);
|
||||
}
|
||||
|
||||
function parse($aMarkers = array()) {
|
||||
return \Flake\Util\Tools::parseTemplateCode(
|
||||
$this->sHtml,
|
||||
$aMarkers
|
||||
);
|
||||
}
|
||||
}
|
59
Core/Frameworks/Flake/Core/View.php
Normal file
59
Core/Frameworks/Flake/Core/View.php
Normal file
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://flake.codr.fr
|
||||
#
|
||||
# This script is part of the Flake project. The Flake
|
||||
# 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 Flake\Core;
|
||||
|
||||
abstract class View extends \Flake\Core\FLObject {
|
||||
protected $aData;
|
||||
|
||||
public function __construct() {
|
||||
$this->aData = array();
|
||||
}
|
||||
|
||||
public function setData($sName, $mData) {
|
||||
$this->aData[$sName] = $mData;
|
||||
}
|
||||
|
||||
public function getData() {
|
||||
return $this->aData;
|
||||
}
|
||||
|
||||
public function get($sWhat) {
|
||||
if(array_key_exists($sWhat, $this->aData)) {
|
||||
return $this->aData[$sWhat];
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
public function render() {
|
||||
$sTemplatePath = $this->templatesPath();
|
||||
$oTemplate = new \Flake\Core\Template($this->templatesPath());
|
||||
return $oTemplate->parse($this->getData());
|
||||
}
|
||||
|
||||
public abstract function templatesPath();
|
||||
}
|
275
Core/Frameworks/Flake/Framework.php
Normal file
275
Core/Frameworks/Flake/Framework.php
Normal file
|
@ -0,0 +1,275 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://flake.codr.fr
|
||||
#
|
||||
# This script is part of the Flake project. The Flake
|
||||
# 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 Flake;
|
||||
require_once(PROJECT_PATH_ROOT . "Core/Frameworks/Flake/Core/Framework.php"); # Manual require as Classloader not included yet
|
||||
|
||||
class Framework extends \Flake\Core\Framework {
|
||||
|
||||
public static function rmBeginSlash($sString) {
|
||||
if(substr($sString, 0, 1) === "/") {
|
||||
$sString = substr($sString, 1);
|
||||
}
|
||||
|
||||
return $sString;
|
||||
}
|
||||
|
||||
public static function rmEndSlash($sString) {
|
||||
if(substr($sString, -1) === "/") {
|
||||
$sString = substr($sString, 0, -1);
|
||||
}
|
||||
|
||||
return $sString;
|
||||
}
|
||||
|
||||
public static function appendSlash($sString) {
|
||||
if(substr($sString, -1) !== "/") {
|
||||
$sString .= "/";
|
||||
}
|
||||
|
||||
return $sString;
|
||||
}
|
||||
|
||||
public static function prependSlash($sString) {
|
||||
if(substr($sString, 0, 1) !== "/") {
|
||||
$sString = "/" . $sString;
|
||||
}
|
||||
|
||||
return $sString;
|
||||
}
|
||||
|
||||
public static function bootstrap() {
|
||||
|
||||
# Asserting PHP 5.3.0+
|
||||
if(version_compare(PHP_VERSION, '5.3.0', '<')) {
|
||||
die('Flake Fatal Error: Flake requires PHP 5.3.0+ to run properly. Your version is: ' . PHP_VERSION . '.');
|
||||
}
|
||||
|
||||
# Define safehash salt
|
||||
define("PROJECT_SAFEHASH_SALT", "strong-secret-salt");
|
||||
|
||||
# Define absolute server path to Flake Framework
|
||||
define("FLAKE_PATH_ROOT", PROJECT_PATH_ROOT . "Core/Frameworks/Flake/"); # ./
|
||||
|
||||
if(!defined('LF')) {
|
||||
define('LF', chr(10));
|
||||
}
|
||||
|
||||
if(!defined('CR')) {
|
||||
define('CR', chr(13));
|
||||
}
|
||||
|
||||
if(array_key_exists("SERVER_NAME", $_SERVER) && $_SERVER["SERVER_NAME"] === "mongoose") {
|
||||
define("MONGOOSE_SERVER", TRUE);
|
||||
} else {
|
||||
define("MONGOOSE_SERVER", FALSE);
|
||||
}
|
||||
|
||||
# Undo magic_quotes as this cannot be disabled by .htaccess on PHP ran as CGI
|
||||
# Source: http://stackoverflow.com/questions/517008/how-to-turn-off-magic-quotes-on-shared-hosting
|
||||
if(in_array(strtolower(ini_get('magic_quotes_gpc')), array('1', 'on'))) {
|
||||
$_POST = array_map('stripslashes', $_POST);
|
||||
$_GET = array_map('stripslashes', $_GET);
|
||||
$_COOKIE = array_map('stripslashes', $_COOKIE);
|
||||
}
|
||||
|
||||
# Fixing some CGI environments, that prefix HTTP_AUTHORIZATION (forwarded in .htaccess) with "REDIRECT_"
|
||||
if(array_key_exists("REDIRECT_HTTP_AUTHORIZATION", $_SERVER)) {
|
||||
$_SERVER["HTTP_AUTHORIZATION"] = $_SERVER["REDIRECT_HTTP_AUTHORIZATION"];
|
||||
}
|
||||
|
||||
#################################################################################################
|
||||
|
||||
# determine Flake install root path
|
||||
# not using realpath here to avoid symlinks resolution
|
||||
|
||||
define("PROJECT_PATH_CORE", PROJECT_PATH_ROOT . "Core/");
|
||||
define("PROJECT_PATH_CORERESOURCES", PROJECT_PATH_CORE . "Resources/");
|
||||
define("PROJECT_PATH_SPECIFIC", PROJECT_PATH_ROOT . "Specific/");
|
||||
define("PROJECT_PATH_FRAMEWORKS", PROJECT_PATH_CORE . "Frameworks/");
|
||||
define("PROJECT_PATH_WWWROOT", PROJECT_PATH_CORE . "WWWRoot/");
|
||||
|
||||
# Activate Flake class loader
|
||||
require_once(FLAKE_PATH_ROOT . 'Core/ClassLoader.php');
|
||||
\Flake\Core\ClassLoader::register();
|
||||
|
||||
require_once(PROJECT_PATH_CORE . "Distrib.php");
|
||||
|
||||
if(PROJECT_PACKAGE === "regular") {
|
||||
define("PROJECT_PATH_DOCUMENTROOT", PROJECT_PATH_ROOT . "html/");
|
||||
} elseif(PROJECT_PACKAGE === "flat") {
|
||||
define("PROJECT_PATH_DOCUMENTROOT", PROJECT_PATH_ROOT);
|
||||
} else {
|
||||
throw new \Exception("Unrecognized PROJECT_PACKAGE value.");
|
||||
}
|
||||
|
||||
# Determine PROJECT_URI
|
||||
$sScript = substr($_SERVER["SCRIPT_FILENAME"], strlen($_SERVER["DOCUMENT_ROOT"]));
|
||||
$sDirName = str_replace("\\", "/", dirname($sScript)); # fix windows backslashes
|
||||
|
||||
if($sDirName !== ".") {
|
||||
$sDirName = self::appendSlash($sDirName);
|
||||
} else {
|
||||
$sDirName = "/";
|
||||
}
|
||||
|
||||
$sBaseUrl = self::rmBeginSlash(self::appendSlash(substr($sDirName, 0, -1 * strlen(PROJECT_CONTEXT_BASEURI))));
|
||||
define("PROJECT_BASEURI", self::prependSlash($sBaseUrl)); # SabreDAV needs a "/" at the beginning of BASEURL
|
||||
|
||||
$sProtocol = \Flake\Util\Tools::getCurrentProtocol();
|
||||
define("PROJECT_URI", $sProtocol . "://" . self::appendSlash($_SERVER["HTTP_HOST"]) . $sBaseUrl);
|
||||
unset($sScript); unset($sDirName); unset($sBaseUrl); unset($sProtocol);
|
||||
|
||||
#################################################################################################
|
||||
|
||||
require_once(FLAKE_PATH_ROOT . 'Util/Twig/lib/Twig/Autoloader.php');
|
||||
\Twig_Autoloader::register();
|
||||
|
||||
# Include Flake Framework config
|
||||
require_once(FLAKE_PATH_ROOT . "config.php");
|
||||
|
||||
# Determine Router class
|
||||
$GLOBALS["ROUTER"] = \Flake\Util\Tools::router();
|
||||
|
||||
if(!\Flake\Util\Tools::isCliPhp()) {
|
||||
ini_set("html_errors", TRUE);
|
||||
session_start();
|
||||
}
|
||||
|
||||
setlocale(LC_ALL, FLAKE_LOCALE);
|
||||
date_default_timezone_set(FLAKE_TIMEZONE);
|
||||
|
||||
$GLOBALS["TEMPLATESTACK"] = array();
|
||||
|
||||
$aUrlInfo = parse_url(PROJECT_URI);
|
||||
define("FLAKE_DOMAIN", $_SERVER["HTTP_HOST"]);
|
||||
define("FLAKE_URIPATH", \Flake\Util\Tools::stripBeginSlash($aUrlInfo["path"]));
|
||||
unset($aUrlInfo);
|
||||
|
||||
|
||||
# Include Project config
|
||||
# NOTE: DB initialization and App config files inclusion
|
||||
# do not break execution if not properly executed, as
|
||||
# these errors will have to be caught later in the process
|
||||
# notably by the App install tool, if available; breaking right now
|
||||
# would forbid such install tool forwarding, for instance
|
||||
|
||||
$sConfigPath = PROJECT_PATH_SPECIFIC . "config.php";
|
||||
$sConfigSystemPath = PROJECT_PATH_SPECIFIC . "config.system.php";
|
||||
|
||||
if(file_exists($sConfigPath)) {
|
||||
require_once($sConfigPath);
|
||||
}
|
||||
|
||||
if(file_exists($sConfigSystemPath)) {
|
||||
require_once($sConfigSystemPath);
|
||||
}
|
||||
|
||||
self::initDb();
|
||||
}
|
||||
|
||||
protected static function initDb() {
|
||||
|
||||
if(defined("PROJECT_DB_MYSQL") && PROJECT_DB_MYSQL === TRUE) {
|
||||
self::initDbMysql();
|
||||
} else {
|
||||
self::initDbSqlite();
|
||||
}
|
||||
}
|
||||
|
||||
protected static function initDbSqlite() {
|
||||
# Asserting DB filepath is set
|
||||
if(!defined("PROJECT_SQLITE_FILE")) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
# Asserting DB file exists
|
||||
if(!file_exists(PROJECT_SQLITE_FILE)) {
|
||||
die("<h3>DB file does not exist. To create it, please copy '<span style='font-family: monospace; background: yellow;'>Core/Resources/Db/SQLite/db.sqlite</span>' to '<span style='font-family: monospace;background: yellow;'>" . PROJECT_SQLITE_FILE . "</span>'</h3>");
|
||||
}
|
||||
|
||||
# Asserting DB file is readable
|
||||
if(!is_readable(PROJECT_SQLITE_FILE)) {
|
||||
die("<h3>DB file is not readable. Please give read permissions on file '<span style='font-family: monospace; background: yellow;'>" . PROJECT_SQLITE_FILE . "</span>'</h3>");
|
||||
}
|
||||
|
||||
# Asserting DB file is writable
|
||||
if(!is_writable(PROJECT_SQLITE_FILE)) {
|
||||
die("<h3>DB file is not writable. Please give write permissions on file '<span style='font-family: monospace; background: yellow;'>" . PROJECT_SQLITE_FILE . "</span>'</h3>");
|
||||
}
|
||||
|
||||
# Asserting DB directory is writable
|
||||
if(!is_writable(dirname(PROJECT_SQLITE_FILE))) {
|
||||
die("<h3>The <em>FOLDER</em> containing the DB file is not writable, and it has to.<br />Please give write permissions on folder '<span style='font-family: monospace; background: yellow;'>" . dirname(PROJECT_SQLITE_FILE) . "</span>'</h3>");
|
||||
}
|
||||
|
||||
if(file_exists(PROJECT_SQLITE_FILE) && is_readable(PROJECT_SQLITE_FILE) && !isset($GLOBALS["DB"])) {
|
||||
$GLOBALS["DB"] = new \Flake\Core\Database\Sqlite(PROJECT_SQLITE_FILE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
protected static function initDbMysql() {
|
||||
|
||||
if(!defined("PROJECT_DB_MYSQL_HOST")) {
|
||||
die("<h3>The constant PROJECT_DB_MYSQL_HOST, containing the MySQL host name, is not set.<br />You should set it in Specific/config.system.php</h3>");
|
||||
}
|
||||
|
||||
if(!defined("PROJECT_DB_MYSQL_DBNAME")) {
|
||||
die("<h3>The constant PROJECT_DB_MYSQL_DBNAME, containing the MySQL database name, is not set.<br />You should set it in Specific/config.system.php</h3>");
|
||||
}
|
||||
|
||||
if(!defined("PROJECT_DB_MYSQL_USERNAME")) {
|
||||
die("<h3>The constant PROJECT_DB_MYSQL_USERNAME, containing the MySQL database username, is not set.<br />You should set it in Specific/config.system.php</h3>");
|
||||
}
|
||||
|
||||
if(!defined("PROJECT_DB_MYSQL_PASSWORD")) {
|
||||
die("<h3>The constant PROJECT_DB_MYSQL_PASSWORD, containing the MySQL database password, is not set.<br />You should set it in Specific/config.system.php</h3>");
|
||||
}
|
||||
|
||||
try {
|
||||
$GLOBALS["DB"] = new \Flake\Core\Database\Mysql(
|
||||
PROJECT_DB_MYSQL_HOST,
|
||||
PROJECT_DB_MYSQL_DBNAME,
|
||||
PROJECT_DB_MYSQL_USERNAME,
|
||||
PROJECT_DB_MYSQL_PASSWORD
|
||||
);
|
||||
|
||||
# We now setup the connexion to use UTF8
|
||||
$GLOBALS["DB"]->query("SET NAMES UTF8");
|
||||
} catch(\Exception $e) {
|
||||
#die("<h3>Baïkal was not able to establish a connexion to the configured MySQL database (as configured in Specific/config.system.php).</h3>");
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
public static function isDBInitialized() {
|
||||
return isset($GLOBALS["DB"]) && \Flake\Util\Tools::is_a($GLOBALS["DB"], "\Flake\Core\Database");
|
||||
}
|
||||
}
|
32
Core/Frameworks/Flake/Model/IUser.php
Normal file
32
Core/Frameworks/Flake/Model/IUser.php
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://flake.codr.fr
|
||||
#
|
||||
# This script is part of the Flake project. The Flake
|
||||
# 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 Flake\Model;
|
||||
|
||||
interface IUser {
|
||||
public function isAdmin();
|
||||
public function getDisplayName();
|
||||
}
|
46
Core/Frameworks/Flake/Model/User/Admin.php
Normal file
46
Core/Frameworks/Flake/Model/User/Admin.php
Normal file
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://flake.codr.fr
|
||||
#
|
||||
# This script is part of the Flake project. The Flake
|
||||
# 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 Flake\Model\User;
|
||||
|
||||
class Admin extends \Flake\Core\Model\NoDb {
|
||||
|
||||
public function isAdmin() {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
public function getDisplayName() {
|
||||
return "Admin";
|
||||
}
|
||||
|
||||
public function persist() {
|
||||
|
||||
}
|
||||
|
||||
public function destroy() {
|
||||
|
||||
}
|
||||
}
|
89
Core/Frameworks/Flake/Model/User/Customer.php
Normal file
89
Core/Frameworks/Flake/Model/User/Customer.php
Normal file
|
@ -0,0 +1,89 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://flake.codr.fr
|
||||
#
|
||||
# This script is part of the Flake project. The Flake
|
||||
# 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 Flake\Model\User;
|
||||
|
||||
class Customer extends \Flake\Core\Model\Db implements \Flake\Model\IUser {
|
||||
|
||||
const DATATABLE = "user";
|
||||
const PRIMARYKEY = "uid";
|
||||
const LABELFIELD = "username";
|
||||
|
||||
protected $aData = array(
|
||||
"username" => "",
|
||||
"firstname" => "",
|
||||
"lastname" => "",
|
||||
"email" => "",
|
||||
"password" => "",
|
||||
"salt" => "",
|
||||
"crdate" => 0,
|
||||
"enabled" => 0,
|
||||
);
|
||||
|
||||
public function isAdmin() {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
public function getDisplayName() {
|
||||
return $this->get("firstname") . " " . $this->get("lastname");
|
||||
}
|
||||
|
||||
public function persist() {
|
||||
|
||||
}
|
||||
|
||||
public function destroy() {
|
||||
|
||||
}
|
||||
|
||||
public static function hashPassword($sClearPassword, $sSalt) {
|
||||
return sha1(APP_ENCRYPTION_KEY . ":" . $sClearPassword . ":" . $sSalt);
|
||||
}
|
||||
|
||||
public static function fetchByCredentials($sUsername, $sClearPassword) {
|
||||
# Algorithm:
|
||||
# 1- find the user by username
|
||||
# 2- hash the given password using the salt for this user
|
||||
# 3- compare hashes
|
||||
|
||||
$oUser = self::getBaseRequester()
|
||||
->addClauseEquals("username", $sUsername)
|
||||
->addClauseEquals("enabled", 1)
|
||||
->execute()
|
||||
->first();
|
||||
|
||||
if(is_null($oUser)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if($oUser->get("password") !== self::hashPassword($sClearPassword, $oUser->get("salt"))) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return $oUser;
|
||||
}
|
||||
|
||||
}
|
55
Core/Frameworks/Flake/Util/Frameworks.php
Normal file
55
Core/Frameworks/Flake/Util/Frameworks.php
Normal file
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://flake.codr.fr
|
||||
#
|
||||
# This script is part of the Flake project. The Flake
|
||||
# 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 Flake\Util;
|
||||
|
||||
class Frameworks extends \Flake\Core\FLObject {
|
||||
private function __construct() { # private constructor to force static class
|
||||
}
|
||||
|
||||
public function isAFramework($sName) {
|
||||
$sName = trim(\Flake\Util\Tools::trimSlashes($sName));
|
||||
if($sName === "" || $sName === "." || $sName === "..") {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$sFrameworkPath = PROJECT_PATH_FRAMEWORKS . $sName;
|
||||
return file_exists($sFrameworkPath) && is_dir($sFrameworkPath);
|
||||
}
|
||||
|
||||
public static function enabled($sFramework) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
# TODO: Create a 'Framework' Model
|
||||
public function getPath($sName) {
|
||||
if(self::isAFramework($sName)) {
|
||||
throw new \Flake\Core\Exception(htmlspecialchars($$sName) . " is not a framework.", $sName);
|
||||
}
|
||||
|
||||
return \Flake\Util\Tools::appendSlash(PROJECT_PATH_FRAMEWORKS . $sName);
|
||||
}
|
||||
}
|
66
Core/Frameworks/Flake/Util/Profiler.php
Normal file
66
Core/Frameworks/Flake/Util/Profiler.php
Normal file
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://flake.codr.fr
|
||||
#
|
||||
# This script is part of the Flake project. The Flake
|
||||
# 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 Flake\Util;
|
||||
|
||||
class Profiler extends \Flake\Core\FLObject {
|
||||
|
||||
protected static $TUSAGE;
|
||||
protected static $RUSAGE;
|
||||
|
||||
protected function __construct() {
|
||||
# Static class
|
||||
}
|
||||
|
||||
public static function start() {
|
||||
$dat = getrusage();
|
||||
self::$TUSAGE = microtime(TRUE);
|
||||
self::$RUSAGE = $dat["ru_utime.tv_sec"] * 1e6 + $dat["ru_utime.tv_usec"];
|
||||
}
|
||||
|
||||
public static function cpuUsage() {
|
||||
$dat = getrusage();
|
||||
$tv_usec = (($dat["ru_utime.tv_sec"] * 1e6) + $dat["ru_utime.tv_usec"]) - self::$RUSAGE;
|
||||
$time = (microtime(true) - self::$TUSAGE) * 1e6;
|
||||
|
||||
// cpu per request
|
||||
if($time > 0) {
|
||||
$cpu = number_format(($tv_usec / $time) * 100, 2);
|
||||
} else {
|
||||
$cpu = '0.00';
|
||||
}
|
||||
|
||||
return $cpu;
|
||||
}
|
||||
|
||||
public static function cpuTime() {
|
||||
$dat = getrusage();
|
||||
$tv_usec = (($dat["ru_utime.tv_sec"] * 1e6) + $dat["ru_utime.tv_usec"]) - self::$RUSAGE;
|
||||
$time = (microtime(true) - self::$TUSAGE) * 1e6;
|
||||
$cpuusage = ($tv_usec / $time);
|
||||
return round(($time / 1000) * $cpuusage);
|
||||
}
|
||||
}
|
144
Core/Frameworks/Flake/Util/Router.php
Normal file
144
Core/Frameworks/Flake/Util/Router.php
Normal file
|
@ -0,0 +1,144 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://flake.codr.fr
|
||||
#
|
||||
# This script is part of the Flake project. The Flake
|
||||
# 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 Flake\Util;
|
||||
|
||||
abstract class Router extends \Flake\Core\FLObject {
|
||||
|
||||
static $sURIPath = "";
|
||||
|
||||
/* ----------------------- COMMON METHODS ------------------------------*/
|
||||
|
||||
private function __construct() {
|
||||
# private constructor for static class
|
||||
}
|
||||
|
||||
public static function getRoutes() {
|
||||
reset($GLOBALS["ROUTES"]);
|
||||
return $GLOBALS["ROUTES"];
|
||||
}
|
||||
|
||||
public static function getControllerForRoute($sRoute) {
|
||||
return str_replace("\\Route", "\\Controller", self::getRouteClassForRoute($sRoute));
|
||||
}
|
||||
|
||||
public static function getRouteClassForRoute($sRoute) {
|
||||
$aRoutes = $GLOBALS["ROUTER"]::getRoutes();
|
||||
return $aRoutes[$sRoute];
|
||||
}
|
||||
|
||||
public static function getRouteForController($sController) {
|
||||
|
||||
if($sController{0} !== "\\") {
|
||||
$sController = "\\" . $sController;
|
||||
}
|
||||
|
||||
$aRoutes = $GLOBALS["ROUTER"]::getRoutes();
|
||||
|
||||
reset($aRoutes);
|
||||
while(list($sRoute,) = each($aRoutes)) {
|
||||
if(str_replace("\\Route", "\\Controller", $aRoutes[$sRoute]) === $sController) {
|
||||
return $sRoute;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
public static function route(\Flake\Core\Render\Container &$oRenderContainer) {
|
||||
$sRouteClass = $GLOBALS["ROUTER"]::getRouteClassForRoute(
|
||||
$GLOBALS["ROUTER"]::getCurrentRoute()
|
||||
);
|
||||
|
||||
$sRouteClass::layout($oRenderContainer);
|
||||
}
|
||||
|
||||
public static function buildRouteForController($sController, $aParams = array()) {
|
||||
|
||||
#$aParams = func_get_args();
|
||||
#array_shift($aParams); # stripping $sController
|
||||
if(($sRouteForController = $GLOBALS["ROUTER"]::getRouteForController($sController)) === FALSE) {
|
||||
throw new \Exception("buildRouteForController '" . htmlspecialchars($sController) . "': no route available.");
|
||||
}
|
||||
|
||||
$aRewrittenParams = array();
|
||||
|
||||
$sRouteClass = self::getRouteClassForRoute($sRouteForController);
|
||||
$aParametersMap = $sRouteClass::parametersMap();
|
||||
reset($aParametersMap);
|
||||
foreach($aParametersMap as $sParam => $aMap) {
|
||||
if(!array_key_exists($sParam, $aParams)) {
|
||||
# if parameter not in parameters map, skip !
|
||||
continue;
|
||||
}
|
||||
|
||||
$sUrlToken = $sParam;
|
||||
if(array_key_exists("urltoken", $aMap)) {
|
||||
$sUrlToken = $aMap["urltoken"];
|
||||
}
|
||||
|
||||
$aRewrittenParams[$sUrlToken] = $aParams[$sParam];
|
||||
}
|
||||
|
||||
#array_unshift($aParams, $sRouteForController); # Injecting route as first param
|
||||
#return call_user_func_array($GLOBALS["ROUTER"] . "::buildRoute", $aParams);
|
||||
return $GLOBALS["ROUTER"]::buildRoute($sRouteForController, $aRewrittenParams);
|
||||
}
|
||||
|
||||
public static function buildCurrentRoute(/*[$sParam, $sParam2, ...]*/) {
|
||||
$aParams = func_get_args();
|
||||
$sCurrentRoute = $GLOBALS["ROUTER"]::getCurrentRoute();
|
||||
|
||||
array_unshift($aParams, $sCurrentRoute); # Injecting route as first param
|
||||
return call_user_func_array($GLOBALS["ROUTER"] . "::buildRoute", $aParams);
|
||||
}
|
||||
|
||||
public static function setURIPath($sURIPath) {
|
||||
static::$sURIPath = $sURIPath;
|
||||
}
|
||||
|
||||
public static function getUriPath() {
|
||||
return FLAKE_URIPATH . static::$sURIPath;
|
||||
}
|
||||
|
||||
/* ----------------------- CHANGING METHODS ----------------------------*/
|
||||
|
||||
# this method is likely to change with every Router implementation
|
||||
# should be abstract, but is not, because of PHP's strict standards
|
||||
public static function buildRoute($sRoute, $aParams/* [, $sParam, $sParam2, ...] */) {
|
||||
|
||||
}
|
||||
|
||||
# should be abstract, but is not, because of PHP's strict standards
|
||||
public static function getCurrentRoute() {
|
||||
|
||||
}
|
||||
|
||||
# should be abstract, but is not, because of PHP's strict standards
|
||||
public static function getURLParams() {
|
||||
|
||||
}
|
||||
}
|
153
Core/Frameworks/Flake/Util/Router/QuestionMarkRewrite.php
Normal file
153
Core/Frameworks/Flake/Util/Router/QuestionMarkRewrite.php
Normal file
|
@ -0,0 +1,153 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://flake.codr.fr
|
||||
#
|
||||
# This script is part of the Flake project. The Flake
|
||||
# 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 Flake\Util\Router;
|
||||
|
||||
class QuestionMarkRewrite extends \Flake\Util\Router {
|
||||
|
||||
public static function getCurrentRoute() {
|
||||
|
||||
$aMatches = array();
|
||||
$sRouteTokens = implode("/", self::getRouteTokens());
|
||||
|
||||
$aRoutes = self::getRoutes();
|
||||
reset($aRoutes);
|
||||
foreach($aRoutes as $sDefinedRoute => $sDefinedController) {
|
||||
|
||||
if(strpos($sRouteTokens, $sDefinedRoute) === 0) {
|
||||
|
||||
# found a match
|
||||
$iSlashCount = substr_count($sDefinedRoute, "/");
|
||||
if(!array_key_exists($iSlashCount, $aMatches)) {
|
||||
$aMatches[$iSlashCount] = array();
|
||||
}
|
||||
|
||||
$aMatches[$iSlashCount][] = $sDefinedRoute;
|
||||
}
|
||||
}
|
||||
|
||||
if(empty($aMatches)) {
|
||||
return "default";
|
||||
}
|
||||
|
||||
$aBestMatches = array_pop($aMatches); // obtains the deepest matching route (higher number of slashes)
|
||||
return array_shift($aBestMatches); // first route amongst best matches
|
||||
}
|
||||
|
||||
public static function buildRoute($sRoute, $aParams = array()/* [, $sParam, $sParam2, ...] */) {
|
||||
# $aParams = func_get_args();
|
||||
# array_shift($aParams); # Stripping $sRoute
|
||||
|
||||
# $sParams = implode("/", $aParams);
|
||||
|
||||
$aParamsSegments = array();
|
||||
reset($aParams);
|
||||
foreach($aParams as $sParamName => $sParamValue) {
|
||||
$aParamsSegments[] = rawurlencode($sParamName) . "/" . rawurlencode($sParamValue);
|
||||
}
|
||||
|
||||
$sParams = implode("/", $aParamsSegments);
|
||||
|
||||
if(trim($sParams) !== "") {
|
||||
$sParams .= "/";
|
||||
}
|
||||
|
||||
if($sRoute === "default" && empty($aParams)) {
|
||||
$sUrl = "/";
|
||||
} else {
|
||||
$sUrl = "/" . $sRoute . "/" . $sParams;
|
||||
}
|
||||
|
||||
$sUriPath = self::getUriPath();
|
||||
if($sUriPath === "" || $sUriPath === "/") {
|
||||
if($sUrl !== "/") {
|
||||
$sUrl = "?" . $sUrl;
|
||||
}
|
||||
} else {
|
||||
if($sUrl !== "/") {
|
||||
$sUrl = "/" . self::getUriPath() . "?" . $sUrl;
|
||||
} else {
|
||||
$sUrl = "/" . self::getUriPath();
|
||||
}
|
||||
}
|
||||
|
||||
return $sUrl;
|
||||
}
|
||||
|
||||
protected static function getUrlTokens() {
|
||||
$sQuery = "";
|
||||
$sUrl = \Flake\Util\Tools::stripBeginSlash(\Flake\Util\Tools::getCurrentUrl());
|
||||
$aUrlParts = parse_url($sUrl);
|
||||
|
||||
$aParams = array();
|
||||
if(array_key_exists("query", $aUrlParts)) {
|
||||
$aParams = explode("/", "?" . $aUrlParts["query"]);
|
||||
}
|
||||
|
||||
return $aParams;
|
||||
}
|
||||
|
||||
protected static function getRouteTokens() {
|
||||
$aUrlTokens = self::getUrlTokens();
|
||||
|
||||
if(!empty($aUrlTokens)) {
|
||||
return array_slice($aUrlTokens, 1);
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
public static function getURLParams() {
|
||||
$aTokens = self::getRouteTokens();
|
||||
|
||||
# stripping route
|
||||
if(!empty($aTokens)) {
|
||||
|
||||
$sRouteUrl = implode("/", $aTokens);
|
||||
$sCurrentRoute = $GLOBALS["ROUTER"]::getCurrentRoute();
|
||||
|
||||
if(strpos($sRouteUrl, $sCurrentRoute) === FALSE) {
|
||||
throw new \Exception("Flake\Util\Router\QuestionMarkRewrite::getURLParams(): unrecognized route.");
|
||||
}
|
||||
|
||||
$sParams = \Flake\Util\Tools::trimSlashes(substr($sRouteUrl, strlen($sCurrentRoute)));
|
||||
|
||||
$aParams = array();
|
||||
if($sParams !== "") {
|
||||
$aParams = explode("/", $sParams);
|
||||
}
|
||||
|
||||
reset($aParams);
|
||||
foreach($aParams as $sParam => $sValue) {
|
||||
$aParams[$sParam] = rawurldecode($sValue);
|
||||
}
|
||||
|
||||
return $aParams;
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
}
|
764
Core/Frameworks/Flake/Util/Tools.php
Normal file
764
Core/Frameworks/Flake/Util/Tools.php
Normal file
|
@ -0,0 +1,764 @@
|
|||
<?php
|
||||
#################################################################
|
||||
# Copyright notice
|
||||
#
|
||||
# (c) 2012 Jérôme Schneider <mail@jeromeschneider.fr>
|
||||
# All rights reserved
|
||||
#
|
||||
# http://flake.codr.fr
|
||||
#
|
||||
# This script is part of the Flake project. The Flake
|
||||
# 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 Flake\Util;
|
||||
|
||||
class Tools extends \Flake\Core\FLObject {
|
||||
|
||||
private function __construct() { # private constructor to force static class
|
||||
}
|
||||
|
||||
public static function getCurrentUrl() {
|
||||
if(MONGOOSE_SERVER) {
|
||||
$sUrl = $GLOBALS["_SERVER"]["REQUEST_URI"];
|
||||
if(array_key_exists("QUERY_STRING", $GLOBALS["_SERVER"]) && trim($GLOBALS["_SERVER"]["QUERY_STRING"]) !== "") {
|
||||
$sUrl .= "?" . $GLOBALS["_SERVER"]["QUERY_STRING"];
|
||||
}
|
||||
} else {
|
||||
$sUrl = $GLOBALS["_SERVER"]["REQUEST_URI"]; # Would be REDIRECT_URL for ServerRewrite
|
||||
}
|
||||
|
||||
return $sUrl;
|
||||
}
|
||||
|
||||
public static function getCurrentProtocol() {
|
||||
if((!empty($GLOBALS["_SERVER"]["HTTPS"]) && $GLOBALS["_SERVER"]['HTTPS'] !== 'off') || intval($_SERVER['SERVER_PORT']) === 443) {
|
||||
return "https";
|
||||
}
|
||||
|
||||
return "http";
|
||||
}
|
||||
|
||||
public static function deCamelCase($sString, $sGlue=" ") {
|
||||
$sSep = md5(rand());
|
||||
$sRes = preg_replace('/(?!^)[[:upper:]][[:lower:]]/', '$0', preg_replace('/(?!^)[[:upper:]]+/', $sSep . '$0', $sString));
|
||||
if($sGlue !== "" && preg_match('/^[[:upper:]].*/', $sRes)) {
|
||||
$sRes = $sSep . $sRes;
|
||||
}
|
||||
|
||||
return str_replace($sSep, $sGlue, $sRes);
|
||||
}
|
||||
|
||||
public static function serverToRelativeWebPath($sAbsPath) {
|
||||
return "/" . str_replace(PROJECT_PATH_WWWROOT, "", $sAbsPath);
|
||||
}
|
||||
|
||||
public static function view_array($array_in) {
|
||||
if (is_array($array_in)) {
|
||||
$result='<table border="1" cellpadding="1" cellspacing="0" bgcolor="white">';
|
||||
if (!count($array_in)) {$result.= '<tr><td><font face="Verdana,Arial" size="1"><b>'.htmlspecialchars("EMPTY!").'</b></font></td></tr>';}
|
||||
while (list($key,$val)=each($array_in)) {
|
||||
$result.= '<tr><td valign="top"><font face="Verdana,Arial" size="1">'.htmlspecialchars((string)$key).'</font></td><td>';
|
||||
if (is_array($array_in[$key])) {
|
||||
$result.= \Flake\Util\Tools::view_array($array_in[$key]);
|
||||
} else {
|
||||
if(is_object($val)) {
|
||||
if(method_exists($val, "__toString")) {
|
||||
$sWhat = nl2br(htmlspecialchars((string)$val));
|
||||
} else {
|
||||
$sWhat = nl2br(htmlspecialchars(get_class($val)));
|
||||
}
|
||||
} elseif(is_bool($val)) {
|
||||
$sWhat = ($val === TRUE ? "boolean:TRUE" : "boolean:FALSE");
|
||||
} else {
|
||||
$sWhat = nl2br(htmlspecialchars((string)$val));
|
||||
}
|
||||
|
||||
$result .= '<font face="Verdana,Arial" size="1" color="red">' . $sWhat . '<br /></font>';
|
||||
}
|
||||
|
||||
$result.= '</td></tr>';
|
||||
}
|
||||
$result.= '</table>';
|
||||
} else {
|
||||
$result = '<table border="1" cellpadding="1" cellspacing="0" bgcolor="white">
|
||||
<tr>
|
||||
<td><font face="Verdana,Arial" size="1" color="red">'.nl2br(htmlspecialchars((string)$array_in)).'<br /></font></td>
|
||||
</tr>
|
||||
</table>'; // Output it as a string.
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function debug($var="",$brOrHeader=0) {
|
||||
if($brOrHeader === 0) {
|
||||
try {
|
||||
$trail = debug_backtrace();
|
||||
$trail = array_reverse($trail);
|
||||
array_pop($trail); // la ligne d'appel à debug
|
||||
array_pop($trail); // la ligne d'appel à debug
|
||||
$aLastNode = array_pop($trail); // l'appel qui nous intéresse
|
||||
|
||||
if(array_key_exists("class", $aLastNode)) {
|
||||
$sClass = @strval($aLastNode["class"]);
|
||||
} else {
|
||||
$sClass = "";
|
||||
}
|
||||
|
||||
if(array_key_exists("type", $aLastNode)) {
|
||||
$sType = @strval($aLastNode["type"]);
|
||||
} else {
|
||||
$sType = "";
|
||||
}
|
||||
|
||||
$brOrHeader = $sClass.$sType.@strval($aLastNode['function']);
|
||||
} catch(\Exception $e) {
|
||||
$brOrHeader = "Undetermined context";
|
||||
}
|
||||
}
|
||||
|
||||
if ($brOrHeader) {
|
||||
echo '<table border="0" cellpadding="0" cellspacing="0" bgcolor="white" style="border:0px; margin-top:3px; margin-bottom:3px;"><tr><td style="background-color:#bbbbbb; font-family: verdana,arial; font-weight: bold; font-size: 10px;">'.htmlspecialchars((string)$brOrHeader).'</td></tr><tr><td>';
|
||||
}
|
||||
|
||||
if (is_array($var)) {
|
||||
echo \Flake\Util\Tools::view_array($var);
|
||||
} elseif (is_object($var)) {
|
||||
echo '<b>|Object:<pre>';
|
||||
print_r($var);
|
||||
echo '</pre>|</b>';
|
||||
} elseif ((string)$var!='') {
|
||||
echo '<b>|'.htmlspecialchars((string)$var).'|</b>';
|
||||
} else {
|
||||
echo '<b>| debug |</b>';
|
||||
}
|
||||
|
||||
if ($brOrHeader) {
|
||||
echo '</td></tr></table>';
|
||||
}
|
||||
}
|
||||
|
||||
public static function debug_trail() {
|
||||
$trail = debug_backtrace();
|
||||
$trail = array_reverse($trail);
|
||||
array_pop($trail);
|
||||
|
||||
$path = array();
|
||||
foreach($trail as $dat) {
|
||||
$path[] = $dat['class'].$dat['type'].$dat['function'];
|
||||
}
|
||||
|
||||
return implode(' // ',$path);
|
||||
}
|
||||
|
||||
public static function POST($sVar = FALSE) {
|
||||
if($sVar !== FALSE) {
|
||||
$aData = \Flake\Util\Tools::POST();
|
||||
if(array_key_exists($sVar, $aData)) {
|
||||
return $aData[$sVar];
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
return is_array($GLOBALS["_POST"]) ? $GLOBALS["_POST"] : array();
|
||||
}
|
||||
|
||||
public static function GET($sVar = FALSE) {
|
||||
if($sVar !== FALSE) {
|
||||
$aData = \Flake\Util\Tools::GET();
|
||||
if(array_key_exists($sVar, $aData)) {
|
||||
return $aData[$sVar];
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
return is_array($GLOBALS["_GET"]) ? $GLOBALS["_GET"] : array();
|
||||
}
|
||||
|
||||
public static function GP($sVar = FALSE) {
|
||||
if($sVar !== FALSE) {
|
||||
$aData = \Flake\Util\Tools::GP();
|
||||
if(array_key_exists($sVar, $aData)) {
|
||||
return $aData[$sVar];
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
return array_merge(
|
||||
\Flake\Util\Tools::GET(),
|
||||
\Flake\Util\Tools::POST()
|
||||
);
|
||||
}
|
||||
|
||||
public static function safelock($sString) {
|
||||
return substr(md5(PROJECT_SAFEHASH_SALT . ":" . $sString), 0, 5);
|
||||
}
|
||||
|
||||
public static function redirect($sUrl) {
|
||||
header("Location: " . $sUrl);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
public static function redirectUsingMeta($sUrl) {
|
||||
$sDoc = "<html><head><meta http-equiv='refresh' content='0; url=" . $sUrl . "'></meta></head><body></body></html>";
|
||||
echo $sDoc;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
public static function refreshPage() {
|
||||
header("Location: " . \Flake\Util\Tools::getCurrentUrl());
|
||||
exit(0);
|
||||
}
|
||||
|
||||
public static function validEmail($sEmail) {
|
||||
return (filter_var($sEmail, FILTER_VALIDATE_EMAIL) !== FALSE);
|
||||
}
|
||||
|
||||
public static function filterFormInput($sInput) {
|
||||
return strip_tags($sInput);
|
||||
}
|
||||
|
||||
public static function getHumanDate($iStamp) {
|
||||
return ucwords(strftime("%A, %d %B %Y", $iStamp));
|
||||
}
|
||||
|
||||
public static function getHumanTime($iStamp) {
|
||||
return strftime("%Hh%M", $iStamp);
|
||||
}
|
||||
|
||||
public static function trimExplode($string, $delim=",", $removeEmptyValues = false, $limit = 0) {
|
||||
$explodedValues = explode($delim, $string);
|
||||
|
||||
$result = array_map('trim', $explodedValues);
|
||||
|
||||
if ($removeEmptyValues) {
|
||||
$temp = array();
|
||||
foreach($result as $value) {
|
||||
if ($value !== '') {
|
||||
$temp[] = $value;
|
||||
}
|
||||
}
|
||||
$result = $temp;
|
||||
}
|
||||
|
||||
if ($limit != 0) {
|
||||
if ($limit < 0) {
|
||||
$result = array_slice($result, 0, $limit);
|
||||
} elseif (count($result) > $limit) {
|
||||
$lastElements = array_slice($result, $limit - 1);
|
||||
$result = array_slice($result, 0, $limit - 1);
|
||||
$result[] = implode($delim, $lastElements);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Taken from TYPO3
|
||||
* Returns true if the first part of $str matches the string $partStr
|
||||
*
|
||||
* @param string Full string to check
|
||||
* @param string Reference string which must be found as the "first part" of the full string
|
||||
* @return boolean True if $partStr was found to be equal to the first part of $str
|
||||
*/
|
||||
public static function isFirstPartOfStr($str,$partStr) {
|
||||
// Returns true, if the first part of a $str equals $partStr and $partStr is not ''
|
||||
$psLen = strlen($partStr);
|
||||
if ($psLen) {
|
||||
return substr($str,0,$psLen)==(string)$partStr;
|
||||
} else return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Binary-reads a file
|
||||
*
|
||||
* @param string $sPath: absolute server path to file
|
||||
* @return string file contents
|
||||
*/
|
||||
public static function file_readBin($sPath) {
|
||||
$sData = "";
|
||||
$rFile = fopen($sPath, "rb");
|
||||
while(!feof($rFile)) {
|
||||
$sData .= fread($rFile, 1024);
|
||||
}
|
||||
fclose($rFile);
|
||||
|
||||
return $sData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Binary-writes a file
|
||||
*
|
||||
* @param string $sPath: absolute server path to file
|
||||
* @param string $sData: file contents
|
||||
* @param boolean $bUTF8: add UTF8-BOM or not ?
|
||||
* @return void
|
||||
*/
|
||||
public static function file_writeBin($sPath, $sData) {
|
||||
$rFile=fopen($sPath, "wb");
|
||||
fputs($rFile, $sData);
|
||||
fclose($rFile);
|
||||
}
|
||||
|
||||
public static function sendHtmlMail($sToAddress, $sSubject, $sBody, $sFromName, $sFromAddress, $sReplyToName, $sReplyToAddress) {
|
||||
|
||||
$sMessage = <<<TEST
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>Email</title>
|
||||
</head>
|
||||
<body>
|
||||
{$sBody}
|
||||
</body>
|
||||
</html>
|
||||
TEST;
|
||||
|
||||
$sHeaders = "From: " . $sFromName . "<" . $sFromAddress . ">" . "\r\n";
|
||||
$sHeaders .= "Reply-To: " . $sReplyToName . "<" . $sReplyToAddress . ">" . "\r\n";
|
||||
$sHeaders .= "Bcc: " . $sReplyToName . "<" . $sReplyToAddress . ">" . "\r\n";
|
||||
$sHeaders .= "Content-Type: text/html" . "\r\n";
|
||||
|
||||
mail($sToAddress, $sSubject, $sMessage, $sHeaders);
|
||||
}
|
||||
|
||||
public static function shortMD5($sValue) {
|
||||
return strtolower(substr(md5($sValue), 0, 5));
|
||||
}
|
||||
|
||||
public static function overrideFirstWithSecond($sFirst, $sSecond) {
|
||||
if(trim($sSecond) !== "") {
|
||||
return $sSecond;
|
||||
}
|
||||
|
||||
return "" . $sFirst;
|
||||
}
|
||||
|
||||
public static function parseTemplateCode($sCode, $aMarkers) {
|
||||
|
||||
$loader = new \Twig_Loader_String();
|
||||
$twig = new \Twig_Environment($loader);
|
||||
|
||||
return $twig->render($sCode, $aMarkers);
|
||||
}
|
||||
|
||||
|
||||
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(class_exists($class, TRUE)) { # TRUE to autoload 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) {
|
||||
header("HTTP/1.1 404 Not Found");
|
||||
header("Status: 404 Not Found");
|
||||
die("<h1>HTTP Status " . $iCode . " : " . $sMessage . "</h1>");
|
||||
}
|
||||
|
||||
public static function number2Rank($a) {
|
||||
$a = intval($a);
|
||||
|
||||
if ($a === 1) {
|
||||
return "premier";
|
||||
} elseif($a === 2) {
|
||||
return "second";
|
||||
}
|
||||
|
||||
$sNumber = self::number2Human($a);
|
||||
|
||||
$sLastLetter = substr($sNumber, -1, 1);
|
||||
if($sLastLetter === "e") {
|
||||
$sNumber = substr($sNumber, 0, -1);
|
||||
} elseif($sLastLetter === "q") {
|
||||
$sNumber = $sNumber . "u";
|
||||
} elseif($sLastLetter === "f") {
|
||||
$sNumber = substr($sNumber, 0, -1) . "v";
|
||||
}
|
||||
|
||||
return $sNumber . "ième";
|
||||
}
|
||||
|
||||
public static function number2Human($a) {
|
||||
$temp = explode('.',$a);
|
||||
if (isset($temp[1]) && $temp[1]!='') {
|
||||
return self::number2Human($temp[0]).' virgule '.self::number2Human($temp[1]) ;
|
||||
}
|
||||
|
||||
if ($a<0) return 'moins '.self::number2Human(-$a);
|
||||
|
||||
if ($a<17) {
|
||||
switch ($a) {
|
||||
case 0: return 'zero';
|
||||
case 1: return 'un';
|
||||
case 2: return 'deux';
|
||||
case 3: return 'trois';
|
||||
case 4: return 'quatre';
|
||||
case 5: return 'cinq';
|
||||
case 6: return 'six';
|
||||
case 7: return 'sept';
|
||||
case 8: return 'huit';
|
||||
case 9: return 'neuf';
|
||||
case 10: return 'dix';
|
||||
case 11: return 'onze';
|
||||
case 12: return 'douze';
|
||||
case 13: return 'treize';
|
||||
case 14: return 'quatorze';
|
||||
case 15: return 'quinze';
|
||||
case 16: return 'seize';
|
||||
}
|
||||
} else if ($a<20) {
|
||||
return 'dix-' . self::number2Human($a-10);
|
||||
} else if ($a<100) {
|
||||
if ($a%10==0) {
|
||||
switch($a) {
|
||||
case 20: return 'vingt';
|
||||
case 30: return 'trente';
|
||||
case 40: return 'quarante';
|
||||
case 50: return 'cinquante';
|
||||
case 60: return 'soixante';
|
||||
case 70: return 'soixante-dix';
|
||||
case 80: return 'quatre-vingt';
|
||||
case 90: return 'quatre-vingt-dix';
|
||||
}
|
||||
} elseif(substr($a, -1) == 1) {
|
||||
if( ((int)($a/10)*10)<70 ) {
|
||||
return self::number2Human((int)($a/10)*10).'-et-un';
|
||||
} elseif ($a==71) {
|
||||
return 'soixante-et-onze';
|
||||
} elseif ($a==81) {
|
||||
return 'quatre-vingt-un';
|
||||
} elseif ($a==91) {
|
||||
return 'quatre-vingt-onze';
|
||||
}
|
||||
} elseif ($a<70) {
|
||||
return self::number2Human($a-$a%10).'-'.self::number2Human($a%10);
|
||||
} elseif ($a<80) {
|
||||
return self::number2Human(60).'-'.self::number2Human($a%20);
|
||||
} else {
|
||||
return self::number2Human(80).'-'.self::number2Human($a%20);
|
||||
}
|
||||
} else if ($a==100) {
|
||||
return 'cent';
|
||||
} else if ($a<200) {
|
||||
return self::number2Human(100).' '.self::number2Human($a%100);
|
||||
} else if ($a<1000) {
|
||||
return self::number2Human((int)($a/100)).' '.self::number2Human(100).' '.self::number2Human($a%100);
|
||||
} else if ($a==1000) {
|
||||
return 'mille';
|
||||
} else if ($a<2000) {
|
||||
return self::number2Human(1000).' '.self::number2Human($a%1000).' ';
|
||||
} else if ($a<1000000) {
|
||||
return self::number2Human((int)($a/1000)).' '.self::number2Human(1000).' '.self::number2Human($a%1000);
|
||||
}
|
||||
}
|
||||
|
||||
public static function stringToUrlToken($sString) {
|
||||
|
||||
# Taken from TYPO3 extension realurl
|
||||
|
||||
$space = "-";
|
||||
$sString = strtr($sString, ' -+_\'', $space . $space . $space . $space . $space); // convert spaces
|
||||
|
||||
if(function_exists("iconv")) {
|
||||
$sString = iconv('UTF-8', 'ASCII//TRANSLIT', $sString);
|
||||
}
|
||||
|
||||
$sString = strtolower($sString);
|
||||
|
||||
$sString = preg_replace('/[^a-zA-Z0-9\\' . $space . ']/', '', $sString);
|
||||
$sString = preg_replace('/\\' . $space . '{2,}/', $space, $sString); // Convert multiple 'spaces' to a single one
|
||||
$sString = trim($sString, $space);
|
||||
|
||||
return $sString;
|
||||
}
|
||||
|
||||
public static function isCliPhp() {
|
||||
return strtolower(php_sapi_name()) === "cli";
|
||||
}
|
||||
|
||||
public static function getIP() {
|
||||
|
||||
$alt_ip = $_SERVER['REMOTE_ADDR'];
|
||||
|
||||
if(isset($_SERVER['HTTP_CLIENT_IP'])) {
|
||||
$alt_ip = $_SERVER['HTTP_CLIENT_IP'];
|
||||
} else if(isset($_SERVER['HTTP_X_FORWARDED_FOR']) AND preg_match_all('#\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}#s', $_SERVER['HTTP_X_FORWARDED_FOR'], $matches)) {
|
||||
|
||||
// make sure we dont pick up an internal IP defined by RFC1918
|
||||
foreach($matches[0] AS $ip) {
|
||||
if (!preg_match('#^(10|172\.16|192\.168)\.#', $ip)) {
|
||||
$alt_ip = $ip;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (isset($_SERVER['HTTP_FROM'])) {
|
||||
$alt_ip = $_SERVER['HTTP_FROM'];
|
||||
}
|
||||
|
||||
return $alt_ip;
|
||||
}
|
||||
|
||||
public static function getUserAgent() {
|
||||
return $_SERVER['HTTP_USER_AGENT'];
|
||||
}
|
||||
|
||||
###########
|
||||
public static function appendSlash($sString) {
|
||||
return self::appendString($sString, "/");
|
||||
}
|
||||
|
||||
public static function prependSlash($sString) {
|
||||
return self::prependString($sString, "/");
|
||||
}
|
||||
|
||||
public static function stripBeginSlash($sString) {
|
||||
return self::stripBeginString($sString, "/");
|
||||
}
|
||||
|
||||
public static function stripEndSlash($sString) {
|
||||
return self::stripEndString($sString, "/");
|
||||
}
|
||||
|
||||
public static function trimSlashes($sString) {
|
||||
return self::stripBeginSlash(self::stripEndSlash($sString));
|
||||
}
|
||||
|
||||
###########
|
||||
public static function appendString($sString, $sAppend) {
|
||||
if(substr($sString, -1 * strlen($sAppend)) !== $sAppend) {
|
||||
$sString .= $sAppend;
|
||||
}
|
||||
|
||||
return $sString;
|
||||
}
|
||||
|
||||
public static function prependString($sString, $sAppend) {
|
||||
if(substr($sString, 0, 1 * strlen($sAppend)) !== $sAppend) {
|
||||
$sString = $sAppend . $sString;
|
||||
}
|
||||
|
||||
return $sString;
|
||||
}
|
||||
|
||||
public static function stripBeginString($sString, $sAppend) {
|
||||
if(substr($sString, 0, 1 * strlen($sAppend)) === $sAppend) {
|
||||
$sString = substr($sString, strlen($sAppend));
|
||||
}
|
||||
|
||||
return $sString;
|
||||
}
|
||||
|
||||
public static function stripEndString($sString, $sAppend) {
|
||||
if(substr($sString, -1 * strlen($sAppend)) === $sAppend) {
|
||||
$sString = substr($sString, 0, -1 * strlen($sAppend));
|
||||
}
|
||||
|
||||
return $sString;
|
||||
}
|
||||
|
||||
public static function trimStrings($sString, $sAppend) {
|
||||
return self::stripBeginString(self::stripEndString($sString, $sAppend), $sAppend);
|
||||
}
|
||||
|
||||
public static function stringEndsWith($sHaystack, $sNeedle) {
|
||||
return substr($sHaystack, strlen($sNeedle) * -1) === $sNeedle;
|
||||
}
|
||||
|
||||
###########
|
||||
|
||||
public static function router() {
|
||||
return "\Flake\Util\Router\QuestionMarkRewrite";
|
||||
}
|
||||
|
||||
public static function arrayIsAssoc($aArray) {
|
||||
if(!is_array($aArray)) {
|
||||
throw new \Exception("\Flake\Util\Tools::arrayIsAssoc(): parameter has to be an array.");
|
||||
}
|
||||
|
||||
# Taken from http://stackoverflow.com/questions/173400/php-arrays-a-good-way-to-check-if-an-array-is-associative-or-sequential#answer-4254008
|
||||
# count() will return 0 if numeric, and > 0 if assoc, even partially
|
||||
return (bool)count(array_filter(array_keys($aArray), 'is_string'));
|
||||
}
|
||||
|
||||
public static function arrayIsSeq($aArray) {
|
||||
return !self::arrayIsAssoc($aArray);
|
||||
}
|
||||
|
||||
public static function echoAndCutClient($sMessage='') {
|
||||
ignore_user_abort(TRUE);
|
||||
# set_time_limit(0);
|
||||
|
||||
header("Connection: close");
|
||||
header("Content-Length: ".strlen($sMessage));
|
||||
echo $sMessage;
|
||||
echo str_repeat("\r\n", 10); // just to be sure
|
||||
flush();
|
||||
}
|
||||
|
||||
public static function milliseconds() {
|
||||
return intval((microtime(TRUE) * 1000));
|
||||
}
|
||||
|
||||
public static function stopWatch($sWhat) {
|
||||
# return;
|
||||
$iStop = \Flake\Util\Tools::milliseconds();
|
||||
|
||||
$trail = debug_backtrace();
|
||||
$aLastNode = $trail[0]; // l'appel qui nous intéresse
|
||||
$sFile = basename($aLastNode["file"]);
|
||||
$iLine = intval($aLastNode["line"]);
|
||||
|
||||
if(!array_key_exists("FLAKE_STOPWATCHES", $GLOBALS)) {
|
||||
$GLOBALS["FLAKE_STOPWATCHES"] = array();
|
||||
}
|
||||
|
||||
if(!array_key_exists($sWhat, $GLOBALS["FLAKE_STOPWATCHES"])) {
|
||||
$GLOBALS["FLAKE_STOPWATCHES"][$sWhat] = $iStop;
|
||||
} else {
|
||||
$iTime = $iStop - $GLOBALS["FLAKE_STOPWATCHES"][$sWhat];
|
||||
echo "<h3 style='color: silver'><span style='display: inline-block; width: 400px;'>@" . $sFile . "+" . $iLine . ":</span>" . $sWhat . ":" . $iTime . " ms</h1>";
|
||||
flush();
|
||||
}
|
||||
}
|
||||
|
||||
# Taken from http://www.php.net/manual/en/function.gzdecode.php#82930
|
||||
public static function gzdecode($data, &$filename='', &$error='', $maxlength=null) {
|
||||
$len = strlen($data);
|
||||
if ($len < 18 || strcmp(substr($data,0,2),"\x1f\x8b")) {
|
||||
$error = "Not in GZIP format.";
|
||||
return null; // Not GZIP format (See RFC 1952)
|
||||
}
|
||||
$method = ord(substr($data,2,1)); // Compression method
|
||||
$flags = ord(substr($data,3,1)); // Flags
|
||||
if ($flags & 31 != $flags) {
|
||||
$error = "Reserved bits not allowed.";
|
||||
return null;
|
||||
}
|
||||
// NOTE: $mtime may be negative (PHP integer limitations)
|
||||
$mtime = unpack("V", substr($data,4,4));
|
||||
$mtime = $mtime[1];
|
||||
$xfl = substr($data,8,1);
|
||||
$os = substr($data,8,1);
|
||||
$headerlen = 10;
|
||||
$extralen = 0;
|
||||
$extra = "";
|
||||
if ($flags & 4) {
|
||||
// 2-byte length prefixed EXTRA data in header
|
||||
if ($len - $headerlen - 2 < 8) {
|
||||
return false; // invalid
|
||||
}
|
||||
$extralen = unpack("v",substr($data,8,2));
|
||||
$extralen = $extralen[1];
|
||||
if ($len - $headerlen - 2 - $extralen < 8) {
|
||||
return false; // invalid
|
||||
}
|
||||
$extra = substr($data,10,$extralen);
|
||||
$headerlen += 2 + $extralen;
|
||||
}
|
||||
$filenamelen = 0;
|
||||
$filename = "";
|
||||
if ($flags & 8) {
|
||||
// C-style string
|
||||
if ($len - $headerlen - 1 < 8) {
|
||||
return false; // invalid
|
||||
}
|
||||
$filenamelen = strpos(substr($data,$headerlen),chr(0));
|
||||
if ($filenamelen === false || $len - $headerlen - $filenamelen - 1 < 8) {
|
||||
return false; // invalid
|
||||
}
|
||||
$filename = substr($data,$headerlen,$filenamelen);
|
||||
$headerlen += $filenamelen + 1;
|
||||
}
|
||||
$commentlen = 0;
|
||||
$comment = "";
|
||||
if ($flags & 16) {
|
||||
// C-style string COMMENT data in header
|
||||
if ($len - $headerlen - 1 < 8) {
|
||||
return false; // invalid
|
||||
}
|
||||
$commentlen = strpos(substr($data,$headerlen),chr(0));
|
||||
if ($commentlen === false || $len - $headerlen - $commentlen - 1 < 8) {
|
||||
return false; // Invalid header format
|
||||
}
|
||||
$comment = substr($data,$headerlen,$commentlen);
|
||||
$headerlen += $commentlen + 1;
|
||||
}
|
||||
$headercrc = "";
|
||||
if ($flags & 2) {
|
||||
// 2-bytes (lowest order) of CRC32 on header present
|
||||
if ($len - $headerlen - 2 < 8) {
|
||||
return false; // invalid
|
||||
}
|
||||
$calccrc = crc32(substr($data,0,$headerlen)) & 0xffff;
|
||||
$headercrc = unpack("v", substr($data,$headerlen,2));
|
||||
$headercrc = $headercrc[1];
|
||||
if ($headercrc != $calccrc) {
|
||||
$error = "Header checksum failed.";
|
||||
return false; // Bad header CRC
|
||||
}
|
||||
$headerlen += 2;
|
||||
}
|
||||
// GZIP FOOTER
|
||||
$datacrc = unpack("V",substr($data,-8,4));
|
||||
$datacrc = sprintf('%u',$datacrc[1] & 0xFFFFFFFF);
|
||||
$isize = unpack("V",substr($data,-4));
|
||||
$isize = $isize[1];
|
||||
// decompression:
|
||||
$bodylen = $len-$headerlen-8;
|
||||
if ($bodylen < 1) {
|
||||
// IMPLEMENTATION BUG!
|
||||
return null;
|
||||
}
|
||||
$body = substr($data,$headerlen,$bodylen);
|
||||
$data = "";
|
||||
if ($bodylen > 0) {
|
||||
switch ($method) {
|
||||
case 8:
|
||||
// Currently the only supported compression method:
|
||||
$data = gzinflate($body,$maxlength);
|
||||
break;
|
||||
default:
|
||||
$error = "Unknown compression method.";
|
||||
return false;
|
||||
}
|
||||
} // zero-byte body content is allowed
|
||||
// Verifiy CRC32
|
||||
$crc = sprintf("%u",crc32($data));
|
||||
$crcOK = $crc == $datacrc;
|
||||
$lenOK = $isize == strlen($data);
|
||||
if (!$lenOK || !$crcOK) {
|
||||
$error = ( $lenOK ? '' : 'Length check FAILED. ') . ( $crcOK ? '' : 'Checksum FAILED.');
|
||||
return false;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
9
Core/Frameworks/Flake/Util/Twig/AUTHORS
Normal file
9
Core/Frameworks/Flake/Util/Twig/AUTHORS
Normal file
|
@ -0,0 +1,9 @@
|
|||
Twig is written and maintained by the Twig Team:
|
||||
|
||||
Lead Developer:
|
||||
|
||||
- Fabien Potencier <fabien.potencier@symfony-project.org>
|
||||
|
||||
Project Founder:
|
||||
|
||||
- Armin Ronacher <armin.ronacher@active-4.com>
|
501
Core/Frameworks/Flake/Util/Twig/CHANGELOG
Normal file
501
Core/Frameworks/Flake/Util/Twig/CHANGELOG
Normal file
|
@ -0,0 +1,501 @@
|
|||
* 1.8.0 (2012-05-08)
|
||||
|
||||
* enforced interface when adding tests, filters, functions, and node visitors from extensions
|
||||
* fixed a side-effect of the date filter where the timezone might be changed
|
||||
* simplified usage of the autoescape tag; the only (optional) argument is now the escaping strategy or false (with a BC layer)
|
||||
* added a way to dynamically change the auto-escaping strategy according to the template "filename"
|
||||
* changed the autoescape option to also accept a supported escaping strategy (for BC, true is equivalent to html)
|
||||
* added an embed tag
|
||||
|
||||
* 1.7.0 (2012-04-24)
|
||||
|
||||
* fixed a PHP warning when using CIFS
|
||||
* fixed template line number in some exceptions
|
||||
* added an iterable test
|
||||
* added an error when defining two blocks with the same name in a template
|
||||
* added the preserves_safety option for filters
|
||||
* fixed a PHP notice when trying to access a key on a non-object/array variable
|
||||
* enhanced error reporting when the template file is an instance of SplFileInfo
|
||||
* added Twig_Environment::mergeGlobals()
|
||||
* added compilation checks to avoid misuses of the sandbox tag
|
||||
* fixed filesystem loader freshness logic for high traffic websites
|
||||
* fixed random function when charset is null
|
||||
|
||||
* 1.6.5 (2012-04-11)
|
||||
|
||||
* fixed a regression when a template only extends another one without defining any blocks
|
||||
|
||||
* 1.6.4 (2012-04-02)
|
||||
|
||||
* fixed PHP notice in Twig_Error::guessTemplateLine() introduced in 1.6.3
|
||||
* fixed performance when compiling large files
|
||||
* optimized parent template creation when the template does not use dynamic inheritance
|
||||
|
||||
* 1.6.3 (2012-03-22)
|
||||
|
||||
* fixed usage of Z_ADDREF_P for PHP 5.2 in the C extension
|
||||
* fixed compilation of numeric values used in templates when using a locale where the decimal separator is not a dot
|
||||
* made the strategy used to guess the real template file name and line number in exception messages much faster and more accurate
|
||||
|
||||
* 1.6.2 (2012-03-18)
|
||||
|
||||
* fixed sandbox mode when used with inheritance
|
||||
* added preserveKeys support for the slice filter
|
||||
* fixed the date filter when a DateTime instance is passed with a specific timezone
|
||||
* added a trim filter
|
||||
|
||||
* 1.6.1 (2012-02-29)
|
||||
|
||||
* fixed Twig C extension
|
||||
* removed the creation of Twig_Markup instances when not needed
|
||||
* added a way to set the default global timezone for dates
|
||||
* fixed the slice filter on strings when the length is not specified
|
||||
* fixed the creation of the cache directory in case of a race condition
|
||||
|
||||
* 1.6.0 (2012-02-04)
|
||||
|
||||
* fixed raw blocks when used with the whitespace trim option
|
||||
* made a speed optimization to macro calls when imported via the "from" tag
|
||||
* fixed globals, parsers, visitors, filters, tests, and functions management in Twig_Environment when a new one or new extension is added
|
||||
* fixed the attribute function when passing arguments
|
||||
* added slice notation support for the [] operator (syntactic sugar for the slice operator)
|
||||
* added a slice filter
|
||||
* added string support for the reverse filter
|
||||
* fixed the empty test and the length filter for Twig_Markup instances
|
||||
* added a date function to ease date comparison
|
||||
* fixed unary operators precedence
|
||||
* added recursive parsing support in the parser
|
||||
* added string and integer handling for the random function
|
||||
|
||||
* 1.5.1 (2012-01-05)
|
||||
|
||||
* fixed a regression when parsing strings
|
||||
|
||||
* 1.5.0 (2012-01-04)
|
||||
|
||||
* added Traversable objects support for the join filter
|
||||
|
||||
* 1.5.0-RC2 (2011-12-30)
|
||||
|
||||
* added a way to set the default global date interval format
|
||||
* fixed the date filter for DateInterval instances (setTimezone() does not exist for them)
|
||||
* refactored Twig_Template::display() to ease its extension
|
||||
* added a number_format filter
|
||||
|
||||
* 1.5.0-RC1 (2011-12-26)
|
||||
|
||||
* removed the need to quote hash keys
|
||||
* allowed hash keys to be any expression
|
||||
* added a do tag
|
||||
* added a flush tag
|
||||
* added support for dynamically named filters and functions
|
||||
* added a dump function to help debugging templates
|
||||
* added a nl2br filter
|
||||
* added a random function
|
||||
* added a way to change the default format for the date filter
|
||||
* fixed the lexer when an operator ending with a letter ends a line
|
||||
* added string interpolation support
|
||||
* enhanced exceptions for unknown filters, functions, tests, and tags
|
||||
|
||||
* 1.4.0 (2011-12-07)
|
||||
|
||||
* fixed lexer when using big numbers (> PHP_INT_MAX)
|
||||
* added missing preserveKeys argument to the reverse filter
|
||||
* fixed macros containing filter tag calls
|
||||
|
||||
* 1.4.0-RC2 (2011-11-27)
|
||||
|
||||
* removed usage of Reflection in Twig_Template::getAttribute()
|
||||
* added a C extension that can optionally replace Twig_Template::getAttribute()
|
||||
* added negative timestamp support to the date filter
|
||||
|
||||
* 1.4.0-RC1 (2011-11-20)
|
||||
|
||||
* optimized variable access when using PHP 5.4
|
||||
* changed the precedence of the .. operator to be more consistent with languages that implements such a feature like Ruby
|
||||
* added an Exception to Twig_Loader_Array::isFresh() method when the template does not exist to be consistent with other loaders
|
||||
* added Twig_Function_Node to allow more complex functions to have their own Node class
|
||||
* added Twig_Filter_Node to allow more complex filters to have their own Node class
|
||||
* added Twig_Test_Node to allow more complex tests to have their own Node class
|
||||
* added a better error message when a template is empty but contain a BOM
|
||||
* fixed "in" operator for empty strings
|
||||
* fixed the "defined" test and the "default" filter (now works with more than one call (foo.bar.foo) and for both values of the strict_variables option)
|
||||
* changed the way extensions are loaded (addFilter/addFunction/addGlobal/addTest/addNodeVisitor/addTokenParser/addExtension can now be called in any order)
|
||||
* added Twig_Environment::display()
|
||||
* made the escape filter smarter when the encoding is not supported by PHP
|
||||
* added a convert_encoding filter
|
||||
* moved all node manipulations outside the compile() Node method
|
||||
* made several speed optimizations
|
||||
|
||||
* 1.3.0 (2011-10-08)
|
||||
|
||||
no changes
|
||||
|
||||
* 1.3.0-RC1 (2011-10-04)
|
||||
|
||||
* added an optimization for the parent() function
|
||||
* added cache reloading when auto_reload is true and an extension has been modified
|
||||
* added the possibility to force the escaping of a string already marked as safe (instance of Twig_Markup)
|
||||
* allowed empty templates to be used as traits
|
||||
* added traits support for the "parent" function
|
||||
|
||||
* 1.2.0 (2011-09-13)
|
||||
|
||||
no changes
|
||||
|
||||
* 1.2.0-RC1 (2011-09-10)
|
||||
|
||||
* enhanced the exception when a tag remains unclosed
|
||||
* added support for empty Countable objects for the "empty" test
|
||||
* fixed algorithm that determines if a template using inheritance is valid (no output between block definitions)
|
||||
* added better support for encoding problems when escaping a string (available as of PHP 5.4)
|
||||
* added a way to ignore a missing template when using the "include" tag ({% include "foo" ignore missing %})
|
||||
* added support for an array of templates to the "include" and "extends" tags ({% include ['foo', 'bar'] %})
|
||||
* added support for bitwise operators in expressions
|
||||
* added the "attribute" function to allow getting dynamic attributes on variables
|
||||
* added Twig_Loader_Chain
|
||||
* added Twig_Loader_Array::setTemplate()
|
||||
* added an optimization for the set tag when used to capture a large chunk of static text
|
||||
* changed name regex to match PHP one "[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*" (works for blocks, tags, functions, filters, and macros)
|
||||
* removed the possibility to use the "extends" tag from a block
|
||||
* added "if" modifier support to "for" loops
|
||||
|
||||
* 1.1.2 (2011-07-30)
|
||||
|
||||
* fixed json_encode filter on PHP 5.2
|
||||
* fixed regression introduced in 1.1.1 ({{ block(foo|lower) }})
|
||||
* fixed inheritance when using conditional parents
|
||||
* fixed compilation of templates when the body of a child template is not empty
|
||||
* fixed output when a macro throws an exception
|
||||
* fixed a parsing problem when a large chunk of text is enclosed in a comment tag
|
||||
* added PHPDoc for all Token parsers and Core extension functions
|
||||
|
||||
* 1.1.1 (2011-07-17)
|
||||
|
||||
* added a performance optimization in the Optimizer (also helps to lower the number of nested level calls)
|
||||
* made some performance improvement for some edge cases
|
||||
|
||||
* 1.1.0 (2011-06-28)
|
||||
|
||||
* fixed json_encode filter
|
||||
|
||||
* 1.1.0-RC3 (2011-06-24)
|
||||
|
||||
* fixed method case-sensitivity when using the sandbox mode
|
||||
* added timezone support for the date filter
|
||||
* fixed possible security problems with NUL bytes
|
||||
|
||||
* 1.1.0-RC2 (2011-06-16)
|
||||
|
||||
* added an exception when the template passed to "use" is not a string
|
||||
* made 'a.b is defined' not throw an exception if a is not defined (in strict mode)
|
||||
* added {% line \d+ %} directive
|
||||
|
||||
* 1.1.0-RC1 (2011-05-28)
|
||||
|
||||
Flush your cache after upgrading.
|
||||
|
||||
* fixed date filter when using a timestamp
|
||||
* fixed the defined test for some cases
|
||||
* fixed a parsing problem when a large chunk of text is enclosed in a raw tag
|
||||
* added support for horizontal reuse of template blocks (see docs for more information)
|
||||
* added whitespace control modifier to all tags (see docs for more information)
|
||||
* added null as an alias for none (the null test is also an alias for the none test now)
|
||||
* made TRUE, FALSE, NONE equivalent to their lowercase counterparts
|
||||
* wrapped all compilation and runtime exceptions with Twig_Error_Runtime and added logic to guess the template name and line
|
||||
* moved display() method to Twig_Template (generated templates should now use doDisplay() instead)
|
||||
|
||||
* 1.0.0 (2011-03-27)
|
||||
|
||||
* fixed output when using mbstring
|
||||
* fixed duplicate call of methods when using the sandbox
|
||||
* made the charset configurable for the escape filter
|
||||
|
||||
* 1.0.0-RC2 (2011-02-21)
|
||||
|
||||
* changed the way {% set %} works when capturing (the content is now marked as safe)
|
||||
* added support for macro name in the endmacro tag
|
||||
* make Twig_Error compatible with PHP 5.3.0 >
|
||||
* fixed an infinite loop on some Windows configurations
|
||||
* fixed the "length" filter for numbers
|
||||
* fixed Template::getAttribute() as properties in PHP are case sensitive
|
||||
* removed coupling between Twig_Node and Twig_Template
|
||||
* fixed the ternary operator precedence rule
|
||||
|
||||
* 1.0.0-RC1 (2011-01-09)
|
||||
|
||||
Backward incompatibilities:
|
||||
|
||||
* the "items" filter, which has been deprecated for quite a long time now, has been removed
|
||||
* the "range" filter has been converted to a function: 0|range(10) -> range(0, 10)
|
||||
* the "constant" filter has been converted to a function: {{ some_date|date('DATE_W3C'|constant) }} -> {{ some_date|date(constant('DATE_W3C')) }}
|
||||
* the "cycle" filter has been converted to a function: {{ ['odd', 'even']|cycle(i) }} -> {{ cycle(['odd', 'even'], i) }}
|
||||
* the "for" tag does not support "joined by" anymore
|
||||
* the "autoescape" first argument is now "true"/"false" (instead of "on"/"off")
|
||||
* the "parent" tag has been replaced by a "parent" function ({{ parent() }} instead of {% parent %})
|
||||
* the "display" tag has been replaced by a "block" function ({{ block('title') }} instead of {% display title %})
|
||||
* removed the grammar and simple token parser (moved to the Twig Extensions repository)
|
||||
|
||||
Changes:
|
||||
|
||||
* added "needs_context" option for filters and functions (the context is then passed as a first argument)
|
||||
* added global variables support
|
||||
* made macros return their value instead of echoing directly (fixes calling a macro in sandbox mode)
|
||||
* added the "from" tag to import macros as functions
|
||||
* added support for functions (a function is just syntactic sugar for a getAttribute() call)
|
||||
* made macros callable when sandbox mode is enabled
|
||||
* added an exception when a macro uses a reserved name
|
||||
* the "default" filter now uses the "empty" test instead of just checking for null
|
||||
* added the "empty" test
|
||||
|
||||
* 0.9.10 (2010-12-16)
|
||||
|
||||
Backward incompatibilities:
|
||||
|
||||
* The Escaper extension is enabled by default, which means that all displayed
|
||||
variables are now automatically escaped. You can revert to the previous
|
||||
behavior by removing the extension via $env->removeExtension('escaper')
|
||||
or just set the 'autoescape' option to 'false'.
|
||||
* removed the "without loop" attribute for the "for" tag (not needed anymore
|
||||
as the Optimizer take care of that for most cases)
|
||||
* arrays and hashes have now a different syntax
|
||||
* arrays keep the same syntax with square brackets: [1, 2]
|
||||
* hashes now use curly braces (["a": "b"] should now be written as {"a": "b"})
|
||||
* support for "arrays with keys" and "hashes without keys" is not supported anymore ([1, "foo": "bar"] or {"foo": "bar", 1})
|
||||
* the i18n extension is now part of the Twig Extensions repository
|
||||
|
||||
Changes:
|
||||
|
||||
* added the merge filter
|
||||
* removed 'is_escaper' option for filters (a left over from the previous version) -- you must use 'is_safe' now instead
|
||||
* fixed usage of operators as method names (like is, in, and not)
|
||||
* changed the order of execution for node visitors
|
||||
* fixed default() filter behavior when used with strict_variables set to on
|
||||
* fixed filesystem loader compatibility with PHAR files
|
||||
* enhanced error messages when an unexpected token is parsed in an expression
|
||||
* fixed filename not being added to syntax error messages
|
||||
* added the autoescape option to enable/disable autoescaping
|
||||
* removed the newline after a comment (mimicks PHP behavior)
|
||||
* added a syntax error exception when parent block is used on a template that does not extend another one
|
||||
* made the Escaper extension enabled by default
|
||||
* fixed sandbox extension when used with auto output escaping
|
||||
* fixed escaper when wrapping a Twig_Node_Print (the original class must be preserved)
|
||||
* added an Optimizer extension (enabled by default; optimizes "for" loops and "raw" filters)
|
||||
* added priority to node visitors
|
||||
|
||||
* 0.9.9 (2010-11-28)
|
||||
|
||||
Backward incompatibilities:
|
||||
* the self special variable has been renamed to _self
|
||||
* the odd and even filters are now tests:
|
||||
{{ foo|odd }} must now be written {{ foo is odd }}
|
||||
* the "safe" filter has been renamed to "raw"
|
||||
* in Node classes,
|
||||
sub-nodes are now accessed via getNode() (instead of property access)
|
||||
attributes via getAttribute() (instead of array access)
|
||||
* the urlencode filter had been renamed to url_encode
|
||||
* the include tag now merges the passed variables with the current context by default
|
||||
(the old behavior is still possible by adding the "only" keyword)
|
||||
* moved Exceptions to Twig_Error_* (Twig_SyntaxError/Twig_RuntimeError are now Twig_Error_Syntax/Twig_Error_Runtime)
|
||||
* removed support for {{ 1 < i < 3 }} (use {{ i > 1 and i < 3 }} instead)
|
||||
* the "in" filter has been removed ({{ a|in(b) }} should now be written {{ a in b }})
|
||||
|
||||
Changes:
|
||||
* added file and line to Twig_Error_Runtime exceptions thrown from Twig_Template
|
||||
* changed trans tag to accept any variable for the plural count
|
||||
* fixed sandbox mode (__toString() method check was not enforced if called implicitly from complex statements)
|
||||
* added the ** (power) operator
|
||||
* changed the algorithm used for parsing expressions
|
||||
* added the spaceless tag
|
||||
* removed trim_blocks option
|
||||
* added support for is*() methods for attributes (foo.bar now looks for foo->getBar() or foo->isBar())
|
||||
* changed all exceptions to extend Twig_Error
|
||||
* fixed unary expressions ({{ not(1 or 0) }})
|
||||
* fixed child templates (with an extend tag) that uses one or more imports
|
||||
* added support for {{ 1 not in [2, 3] }} (more readable than the current {{ not (1 in [2, 3]) }})
|
||||
* escaping has been rewritten
|
||||
* the implementation of template inheritance has been rewritten
|
||||
(blocks can now be called individually and still work with inheritance)
|
||||
* fixed error handling for if tag when a syntax error occurs within a subparse process
|
||||
* added a way to implement custom logic for resolving token parsers given a tag name
|
||||
* fixed js escaper to be stricter (now uses a whilelist-based js escaper)
|
||||
* added the following filers: "constant", "trans", "replace", "json_encode"
|
||||
* added a "constant" test
|
||||
* fixed objects with __toString() not being autoescaped
|
||||
* fixed subscript expressions when calling __call() (methods now keep the case)
|
||||
* added "test" feature (accessible via the "is" operator)
|
||||
* removed the debug tag (should be done in an extension)
|
||||
* fixed trans tag when no vars are used in plural form
|
||||
* fixed race condition when writing template cache
|
||||
* added the special _charset variable to reference the current charset
|
||||
* added the special _context variable to reference the current context
|
||||
* renamed self to _self (to avoid conflict)
|
||||
* fixed Twig_Template::getAttribute() for protected properties
|
||||
|
||||
* 0.9.8 (2010-06-28)
|
||||
|
||||
Backward incompatibilities:
|
||||
* the trans tag plural count is now attached to the plural tag:
|
||||
old: `{% trans count %}...{% plural %}...{% endtrans %}`
|
||||
new: `{% trans %}...{% plural count %}...{% endtrans %}`
|
||||
|
||||
* added a way to translate strings coming from a variable ({% trans var %})
|
||||
* fixed trans tag when used with the Escaper extension
|
||||
* fixed default cache umask
|
||||
* removed Twig_Template instances from the debug tag output
|
||||
* fixed objects with __isset() defined
|
||||
* fixed set tag when used with a capture
|
||||
* fixed type hinting for Twig_Environment::addFilter() method
|
||||
|
||||
* 0.9.7 (2010-06-12)
|
||||
|
||||
Backward incompatibilities:
|
||||
* changed 'as' to '=' for the set tag ({% set title as "Title" %} must now be {% set title = "Title" %})
|
||||
* removed the sandboxed attribute of the include tag (use the new sandbox tag instead)
|
||||
* refactored the Node system (if you have custom nodes, you will have to update them to use the new API)
|
||||
|
||||
* added self as a special variable that refers to the current template (useful for importing macros from the current template)
|
||||
* added Twig_Template instance support to the include tag
|
||||
* added support for dynamic and conditional inheritance ({% extends some_var %} and {% extends standalone ? "minimum" : "base" %})
|
||||
* added a grammar sub-framework to ease the creation of custom tags
|
||||
* fixed the for tag for large arrays (some loop variables are now only available for arrays and objects that implement the Countable interface)
|
||||
* removed the Twig_Resource::resolveMissingFilter() method
|
||||
* fixed the filter tag which did not apply filtering to included files
|
||||
* added a bunch of unit tests
|
||||
* added a bunch of phpdoc
|
||||
* added a sandbox tag in the sandbox extension
|
||||
* changed the date filter to support any date format supported by DateTime
|
||||
* added strict_variable setting to throw an exception when an invalid variable is used in a template (disabled by default)
|
||||
* added the lexer, parser, and compiler as arguments to the Twig_Environment constructor
|
||||
* changed the cache option to only accepts an explicit path to a cache directory or false
|
||||
* added a way to add token parsers, filters, and visitors without creating an extension
|
||||
* added three interfaces: Twig_NodeInterface, Twig_TokenParserInterface, and Twig_FilterInterface
|
||||
* changed the generated code to match the new coding standards
|
||||
* fixed sandbox mode (__toString() method check was not enforced if called implicitly from a simple statement like {{ article }})
|
||||
* added an exception when a child template has a non-empty body (as it is always ignored when rendering)
|
||||
|
||||
* 0.9.6 (2010-05-12)
|
||||
|
||||
* fixed variables defined outside a loop and for which the value changes in a for loop
|
||||
* fixed the test suite for PHP 5.2 and older versions of PHPUnit
|
||||
* added support for __call() in expression resolution
|
||||
* fixed node visiting for macros (macros are now visited by visitors as any other node)
|
||||
* fixed nested block definitions with a parent call (rarely useful but nonetheless supported now)
|
||||
* added the cycle filter
|
||||
* fixed the Lexer when mbstring.func_overload is used with an mbstring.internal_encoding different from ASCII
|
||||
* added a long-syntax for the set tag ({% set foo %}...{% endset %})
|
||||
* unit tests are now powered by PHPUnit
|
||||
* added support for gettext via the `i18n` extension
|
||||
* fixed twig_capitalize_string_filter() and fixed twig_length_filter() when used with UTF-8 values
|
||||
* added a more useful exception if an if tag is not closed properly
|
||||
* added support for escaping strategy in the autoescape tag
|
||||
* fixed lexer when a template has a big chunk of text between/in a block
|
||||
|
||||
* 0.9.5 (2010-01-20)
|
||||
|
||||
As for any new release, don't forget to remove all cached templates after
|
||||
upgrading.
|
||||
|
||||
If you have defined custom filters, you MUST upgrade them for this release. To
|
||||
upgrade, replace "array" with "new Twig_Filter_Function", and replace the
|
||||
environment constant by the "needs_environment" option:
|
||||
|
||||
// before
|
||||
'even' => array('twig_is_even_filter', false),
|
||||
'escape' => array('twig_escape_filter', true),
|
||||
|
||||
// after
|
||||
'even' => new Twig_Filter_Function('twig_is_even_filter'),
|
||||
'escape' => new Twig_Filter_Function('twig_escape_filter', array('needs_environment' => true)),
|
||||
|
||||
If you have created NodeTransformer classes, you will need to upgrade them to
|
||||
the new interface (please note that the interface is not yet considered
|
||||
stable).
|
||||
|
||||
* fixed list nodes that did not extend the Twig_NodeListInterface
|
||||
* added the "without loop" option to the for tag (it disables the generation of the loop variable)
|
||||
* refactored node transformers to node visitors
|
||||
* fixed automatic-escaping for blocks
|
||||
* added a way to specify variables to pass to an included template
|
||||
* changed the automatic-escaping rules to be more sensible and more configurable in custom filters (the documentation lists all the rules)
|
||||
* improved the filter system to allow object methods to be used as filters
|
||||
* changed the Array and String loaders to actually make use of the cache mechanism
|
||||
* included the default filter function definitions in the extension class files directly (Core, Escaper)
|
||||
* added the // operator (like the floor() PHP function)
|
||||
* added the .. operator (as a syntactic sugar for the range filter when the step is 1)
|
||||
* added the in operator (as a syntactic sugar for the in filter)
|
||||
* added the following filters in the Core extension: in, range
|
||||
* added support for arrays (same behavior as in PHP, a mix between lists and dictionaries, arrays and hashes)
|
||||
* enhanced some error messages to provide better feedback in case of parsing errors
|
||||
|
||||
* 0.9.4 (2009-12-02)
|
||||
|
||||
If you have custom loaders, you MUST upgrade them for this release: The
|
||||
Twig_Loader base class has been removed, and the Twig_LoaderInterface has also
|
||||
been changed (see the source code for more information or the documentation).
|
||||
|
||||
* added support for DateTime instances for the date filter
|
||||
* fixed loop.last when the array only has one item
|
||||
* made it possible to insert newlines in tag and variable blocks
|
||||
* fixed a bug when a literal '\n' were present in a template text
|
||||
* fixed bug when the filename of a template contains */
|
||||
* refactored loaders
|
||||
|
||||
* 0.9.3 (2009-11-11)
|
||||
|
||||
This release is NOT backward compatible with the previous releases.
|
||||
|
||||
The loaders do not take the cache and autoReload arguments anymore. Instead,
|
||||
the Twig_Environment class has two new options: cache and auto_reload.
|
||||
Upgrading your code means changing this kind of code:
|
||||
|
||||
$loader = new Twig_Loader_Filesystem('/path/to/templates', '/path/to/compilation_cache', true);
|
||||
$twig = new Twig_Environment($loader);
|
||||
|
||||
to something like this:
|
||||
|
||||
$loader = new Twig_Loader_Filesystem('/path/to/templates');
|
||||
$twig = new Twig_Environment($loader, array(
|
||||
'cache' => '/path/to/compilation_cache',
|
||||
'auto_reload' => true,
|
||||
));
|
||||
|
||||
* deprecated the "items" filter as it is not needed anymore
|
||||
* made cache and auto_reload options of Twig_Environment instead of arguments of Twig_Loader
|
||||
* optimized template loading speed
|
||||
* removed output when an error occurs in a template and render() is used
|
||||
* made major speed improvements for loops (up to 300% on even the smallest loops)
|
||||
* added properties as part of the sandbox mode
|
||||
* added public properties support (obj.item can now be the item property on the obj object)
|
||||
* extended set tag to support expression as value ({% set foo as 'foo' ~ 'bar' %} )
|
||||
* fixed bug when \ was used in HTML
|
||||
|
||||
* 0.9.2 (2009-10-29)
|
||||
|
||||
* made some speed optimizations
|
||||
* changed the cache extension to .php
|
||||
* added a js escaping strategy
|
||||
* added support for short block tag
|
||||
* changed the filter tag to allow chained filters
|
||||
* made lexer more flexible as you can now change the default delimiters
|
||||
* added set tag
|
||||
* changed default directory permission when cache dir does not exist (more secure)
|
||||
* added macro support
|
||||
* changed filters first optional argument to be a Twig_Environment instance instead of a Twig_Template instance
|
||||
* made Twig_Autoloader::autoload() a static method
|
||||
* avoid writing template file if an error occurs
|
||||
* added $ escaping when outputting raw strings
|
||||
* enhanced some error messages to ease debugging
|
||||
* fixed empty cache files when the template contains an error
|
||||
|
||||
* 0.9.1 (2009-10-14)
|
||||
|
||||
* fixed a bug in PHP 5.2.6
|
||||
* fixed numbers with one than one decimal
|
||||
* added support for method calls with arguments ({{ foo.bar('a', 43) }})
|
||||
* made small speed optimizations
|
||||
* made minor tweaks to allow better extensibility and flexibility
|
||||
|
||||
* 0.9.0 (2009-10-12)
|
||||
|
||||
* Initial release
|
31
Core/Frameworks/Flake/Util/Twig/LICENSE
Normal file
31
Core/Frameworks/Flake/Util/Twig/LICENSE
Normal file
|
@ -0,0 +1,31 @@
|
|||
Copyright (c) 2009 by the Twig Team, see AUTHORS for more details.
|
||||
|
||||
Some rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
|
||||
* The names of the contributors may not be used to endorse or
|
||||
promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
17
Core/Frameworks/Flake/Util/Twig/README.markdown
Normal file
17
Core/Frameworks/Flake/Util/Twig/README.markdown
Normal file
|
@ -0,0 +1,17 @@
|
|||
Twig, the flexible, fast, and secure template language for PHP
|
||||
==============================================================
|
||||
|
||||
[](http://travis-ci.org/fabpot/Twig)
|
||||
|
||||
Twig is a template language for PHP, released under the new BSD license (code
|
||||
and documentation).
|
||||
|
||||
Twig uses a syntax similar to the Django and Jinja template languages which
|
||||
inspired the Twig runtime environment.
|
||||
|
||||
More Information
|
||||
----------------
|
||||
|
||||
Read the [documentation][1] for more information.
|
||||
|
||||
[1]: http://twig.sensiolabs.org/documentation
|
46
Core/Frameworks/Flake/Util/Twig/lib/Twig/Autoloader.php
Normal file
46
Core/Frameworks/Flake/Util/Twig/lib/Twig/Autoloader.php
Normal file
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Autoloads Twig classes.
|
||||
*
|
||||
* @package twig
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Autoloader
|
||||
{
|
||||
/**
|
||||
* Registers Twig_Autoloader as an SPL autoloader.
|
||||
*/
|
||||
static public function register()
|
||||
{
|
||||
ini_set('unserialize_callback_func', 'spl_autoload_call');
|
||||
spl_autoload_register(array(new self, 'autoload'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles autoloading of classes.
|
||||
*
|
||||
* @param string $class A class name.
|
||||
*
|
||||
* @return boolean Returns true if the class has been loaded
|
||||
*/
|
||||
static public function autoload($class)
|
||||
{
|
||||
if (0 !== strpos($class, 'Twig')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_file($file = dirname(__FILE__).'/../'.str_replace(array('_', "\0"), array('/', ''), $class).'.php')) {
|
||||
require $file;
|
||||
}
|
||||
}
|
||||
}
|
242
Core/Frameworks/Flake/Util/Twig/lib/Twig/Compiler.php
Normal file
242
Core/Frameworks/Flake/Util/Twig/lib/Twig/Compiler.php
Normal file
|
@ -0,0 +1,242 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Compiles a node to PHP code.
|
||||
*
|
||||
* @package twig
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Compiler implements Twig_CompilerInterface
|
||||
{
|
||||
protected $lastLine;
|
||||
protected $source;
|
||||
protected $indentation;
|
||||
protected $env;
|
||||
protected $debugInfo;
|
||||
protected $sourceOffset;
|
||||
protected $sourceLine;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Twig_Environment $env The twig environment instance
|
||||
*/
|
||||
public function __construct(Twig_Environment $env)
|
||||
{
|
||||
$this->env = $env;
|
||||
$this->debugInfo = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the environment instance related to this compiler.
|
||||
*
|
||||
* @return Twig_Environment The environment instance
|
||||
*/
|
||||
public function getEnvironment()
|
||||
{
|
||||
return $this->env;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current PHP code after compilation.
|
||||
*
|
||||
* @return string The PHP code
|
||||
*/
|
||||
public function getSource()
|
||||
{
|
||||
return $this->source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles a node.
|
||||
*
|
||||
* @param Twig_NodeInterface $node The node to compile
|
||||
* @param integer $indentation The current indentation
|
||||
*
|
||||
* @return Twig_Compiler The current compiler instance
|
||||
*/
|
||||
public function compile(Twig_NodeInterface $node, $indentation = 0)
|
||||
{
|
||||
$this->lastLine = null;
|
||||
$this->source = '';
|
||||
$this->sourceOffset = 0;
|
||||
$this->sourceLine = 0;
|
||||
$this->indentation = $indentation;
|
||||
|
||||
$node->compile($this);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function subcompile(Twig_NodeInterface $node, $raw = true)
|
||||
{
|
||||
if (false === $raw) {
|
||||
$this->addIndentation();
|
||||
}
|
||||
|
||||
$node->compile($this);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a raw string to the compiled code.
|
||||
*
|
||||
* @param string $string The string
|
||||
*
|
||||
* @return Twig_Compiler The current compiler instance
|
||||
*/
|
||||
public function raw($string)
|
||||
{
|
||||
$this->source .= $string;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a string to the compiled code by adding indentation.
|
||||
*
|
||||
* @return Twig_Compiler The current compiler instance
|
||||
*/
|
||||
public function write()
|
||||
{
|
||||
$strings = func_get_args();
|
||||
foreach ($strings as $string) {
|
||||
$this->addIndentation();
|
||||
$this->source .= $string;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addIndentation()
|
||||
{
|
||||
$this->source .= str_repeat(' ', $this->indentation * 4);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a quoted string to the compiled code.
|
||||
*
|
||||
* @param string $value The string
|
||||
*
|
||||
* @return Twig_Compiler The current compiler instance
|
||||
*/
|
||||
public function string($value)
|
||||
{
|
||||
$this->source .= sprintf('"%s"', addcslashes($value, "\0\t\"\$\\"));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a PHP representation of a given value.
|
||||
*
|
||||
* @param mixed $value The value to convert
|
||||
*
|
||||
* @return Twig_Compiler The current compiler instance
|
||||
*/
|
||||
public function repr($value)
|
||||
{
|
||||
if (is_int($value) || is_float($value)) {
|
||||
if (false !== $locale = setlocale(LC_NUMERIC, 0)) {
|
||||
setlocale(LC_NUMERIC, 'C');
|
||||
}
|
||||
|
||||
$this->raw($value);
|
||||
|
||||
if (false !== $locale) {
|
||||
setlocale(LC_NUMERIC, $locale);
|
||||
}
|
||||
} elseif (null === $value) {
|
||||
$this->raw('null');
|
||||
} elseif (is_bool($value)) {
|
||||
$this->raw($value ? 'true' : 'false');
|
||||
} elseif (is_array($value)) {
|
||||
$this->raw('array(');
|
||||
$i = 0;
|
||||
foreach ($value as $key => $value) {
|
||||
if ($i++) {
|
||||
$this->raw(', ');
|
||||
}
|
||||
$this->repr($key);
|
||||
$this->raw(' => ');
|
||||
$this->repr($value);
|
||||
}
|
||||
$this->raw(')');
|
||||
} else {
|
||||
$this->string($value);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds debugging information.
|
||||
*
|
||||
* @param Twig_NodeInterface $node The related twig node
|
||||
*
|
||||
* @return Twig_Compiler The current compiler instance
|
||||
*/
|
||||
public function addDebugInfo(Twig_NodeInterface $node)
|
||||
{
|
||||
if ($node->getLine() != $this->lastLine) {
|
||||
$this->sourceLine += substr_count($this->source, "\n", $this->sourceOffset);
|
||||
$this->sourceOffset = strlen($this->source);
|
||||
$this->debugInfo[$this->sourceLine] = $node->getLine();
|
||||
|
||||
$this->lastLine = $node->getLine();
|
||||
$this->write("// line {$node->getLine()}\n");
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDebugInfo()
|
||||
{
|
||||
return $this->debugInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indents the generated code.
|
||||
*
|
||||
* @param integer $step The number of indentation to add
|
||||
*
|
||||
* @return Twig_Compiler The current compiler instance
|
||||
*/
|
||||
public function indent($step = 1)
|
||||
{
|
||||
$this->indentation += $step;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Outdents the generated code.
|
||||
*
|
||||
* @param integer $step The number of indentation to remove
|
||||
*
|
||||
* @return Twig_Compiler The current compiler instance
|
||||
*/
|
||||
public function outdent($step = 1)
|
||||
{
|
||||
$this->indentation -= $step;
|
||||
|
||||
if ($this->indentation < 0) {
|
||||
throw new Twig_Error('Unable to call outdent() as the indentation would become negative');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Interface implemented by compiler classes.
|
||||
*
|
||||
* @package twig
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
interface Twig_CompilerInterface
|
||||
{
|
||||
/**
|
||||
* Compiles a node.
|
||||
*
|
||||
* @param Twig_NodeInterface $node The node to compile
|
||||
*
|
||||
* @return Twig_CompilerInterface The current compiler instance
|
||||
*/
|
||||
function compile(Twig_NodeInterface $node);
|
||||
|
||||
/**
|
||||
* Gets the current PHP code after compilation.
|
||||
*
|
||||
* @return string The PHP code
|
||||
*/
|
||||
function getSource();
|
||||
}
|
1106
Core/Frameworks/Flake/Util/Twig/lib/Twig/Environment.php
Normal file
1106
Core/Frameworks/Flake/Util/Twig/lib/Twig/Environment.php
Normal file
File diff suppressed because it is too large
Load diff
199
Core/Frameworks/Flake/Util/Twig/lib/Twig/Error.php
Normal file
199
Core/Frameworks/Flake/Util/Twig/lib/Twig/Error.php
Normal file
|
@ -0,0 +1,199 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Twig base exception.
|
||||
*
|
||||
* @package twig
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Error extends Exception
|
||||
{
|
||||
protected $lineno;
|
||||
protected $filename;
|
||||
protected $rawMessage;
|
||||
protected $previous;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $message The error message
|
||||
* @param integer $lineno The template line where the error occurred
|
||||
* @param string $filename The template file name where the error occurred
|
||||
* @param Exception $previous The previous exception
|
||||
*/
|
||||
public function __construct($message, $lineno = -1, $filename = null, Exception $previous = null)
|
||||
{
|
||||
if (version_compare(PHP_VERSION, '5.3.0', '<')) {
|
||||
$this->previous = $previous;
|
||||
parent::__construct('');
|
||||
} else {
|
||||
parent::__construct('', 0, $previous);
|
||||
}
|
||||
|
||||
$this->lineno = $lineno;
|
||||
$this->filename = $filename;
|
||||
|
||||
if (-1 === $this->lineno || null === $this->filename) {
|
||||
$this->guessTemplateInfo();
|
||||
}
|
||||
|
||||
$this->rawMessage = $message;
|
||||
|
||||
$this->updateRepr();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the raw message.
|
||||
*
|
||||
* @return string The raw message
|
||||
*/
|
||||
public function getRawMessage()
|
||||
{
|
||||
return $this->rawMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the filename where the error occurred.
|
||||
*
|
||||
* @return string The filename
|
||||
*/
|
||||
public function getTemplateFile()
|
||||
{
|
||||
return $this->filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the filename where the error occurred.
|
||||
*
|
||||
* @param string $filename The filename
|
||||
*/
|
||||
public function setTemplateFile($filename)
|
||||
{
|
||||
$this->filename = $filename;
|
||||
|
||||
$this->updateRepr();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the template line where the error occurred.
|
||||
*
|
||||
* @return integer The template line
|
||||
*/
|
||||
public function getTemplateLine()
|
||||
{
|
||||
return $this->lineno;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the template line where the error occurred.
|
||||
*
|
||||
* @param integer $lineno The template line
|
||||
*/
|
||||
public function setTemplateLine($lineno)
|
||||
{
|
||||
$this->lineno = $lineno;
|
||||
|
||||
$this->updateRepr();
|
||||
}
|
||||
|
||||
/**
|
||||
* For PHP < 5.3.0, provides access to the getPrevious() method.
|
||||
*
|
||||
* @param string $method The method name
|
||||
* @param array $arguments The parameters to be passed to the method
|
||||
*
|
||||
* @return Exception The previous exception or null
|
||||
*/
|
||||
public function __call($method, $arguments)
|
||||
{
|
||||
if ('getprevious' == strtolower($method)) {
|
||||
return $this->previous;
|
||||
}
|
||||
|
||||
throw new BadMethodCallException(sprintf('Method "Twig_Error::%s()" does not exist.', $method));
|
||||
}
|
||||
|
||||
protected function updateRepr()
|
||||
{
|
||||
$this->message = $this->rawMessage;
|
||||
|
||||
$dot = false;
|
||||
if ('.' === substr($this->message, -1)) {
|
||||
$this->message = substr($this->message, 0, -1);
|
||||
$dot = true;
|
||||
}
|
||||
|
||||
if (null !== $this->filename) {
|
||||
if (is_string($this->filename) || (is_object($this->filename) && method_exists($this->filename, '__toString'))) {
|
||||
$filename = sprintf('"%s"', $this->filename);
|
||||
} else {
|
||||
$filename = json_encode($this->filename);
|
||||
}
|
||||
$this->message .= sprintf(' in %s', $filename);
|
||||
}
|
||||
|
||||
if ($this->lineno >= 0) {
|
||||
$this->message .= sprintf(' at line %d', $this->lineno);
|
||||
}
|
||||
|
||||
if ($dot) {
|
||||
$this->message .= '.';
|
||||
}
|
||||
}
|
||||
|
||||
protected function guessTemplateInfo()
|
||||
{
|
||||
$template = null;
|
||||
foreach (debug_backtrace() as $trace) {
|
||||
if (isset($trace['object']) && $trace['object'] instanceof Twig_Template && 'Twig_Template' !== get_class($trace['object'])) {
|
||||
$template = $trace['object'];
|
||||
|
||||
// update template filename
|
||||
if (null === $this->filename) {
|
||||
$this->filename = $template->getTemplateName();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (null === $template || $this->lineno > -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
$r = new ReflectionObject($template);
|
||||
$file = $r->getFileName();
|
||||
|
||||
$exceptions = array($e = $this);
|
||||
while (($e instanceof self || method_exists($e, 'getPrevious')) && $e = $e->getPrevious()) {
|
||||
$exceptions[] = $e;
|
||||
}
|
||||
|
||||
while ($e = array_pop($exceptions)) {
|
||||
$traces = $e->getTrace();
|
||||
while ($trace = array_shift($traces)) {
|
||||
if (!isset($trace['file']) || !isset($trace['line']) || $file != $trace['file']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($template->getDebugInfo() as $codeLine => $templateLine) {
|
||||
if ($codeLine <= $trace['line']) {
|
||||
// update template line
|
||||
$this->lineno = $templateLine;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
20
Core/Frameworks/Flake/Util/Twig/lib/Twig/Error/Loader.php
Normal file
20
Core/Frameworks/Flake/Util/Twig/lib/Twig/Error/Loader.php
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception thrown when an error occurs during template loading.
|
||||
*
|
||||
* @package twig
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Error_Loader extends Twig_Error
|
||||
{
|
||||
}
|
21
Core/Frameworks/Flake/Util/Twig/lib/Twig/Error/Runtime.php
Normal file
21
Core/Frameworks/Flake/Util/Twig/lib/Twig/Error/Runtime.php
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception thrown when an error occurs at runtime.
|
||||
*
|
||||
* @package twig
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Error_Runtime extends Twig_Error
|
||||
{
|
||||
}
|
21
Core/Frameworks/Flake/Util/Twig/lib/Twig/Error/Syntax.php
Normal file
21
Core/Frameworks/Flake/Util/Twig/lib/Twig/Error/Syntax.php
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exception thrown when a syntax error occurs during lexing or parsing of a template.
|
||||
*
|
||||
* @package twig
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Error_Syntax extends Twig_Error
|
||||
{
|
||||
}
|
488
Core/Frameworks/Flake/Util/Twig/lib/Twig/ExpressionParser.php
Normal file
488
Core/Frameworks/Flake/Util/Twig/lib/Twig/ExpressionParser.php
Normal file
|
@ -0,0 +1,488 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Parses expressions.
|
||||
*
|
||||
* This parser implements a "Precedence climbing" algorithm.
|
||||
*
|
||||
* @see http://www.engr.mun.ca/~theo/Misc/exp_parsing.htm
|
||||
* @see http://en.wikipedia.org/wiki/Operator-precedence_parser
|
||||
*
|
||||
* @package twig
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_ExpressionParser
|
||||
{
|
||||
const OPERATOR_LEFT = 1;
|
||||
const OPERATOR_RIGHT = 2;
|
||||
|
||||
protected $parser;
|
||||
protected $unaryOperators;
|
||||
protected $binaryOperators;
|
||||
|
||||
public function __construct(Twig_Parser $parser, array $unaryOperators, array $binaryOperators)
|
||||
{
|
||||
$this->parser = $parser;
|
||||
$this->unaryOperators = $unaryOperators;
|
||||
$this->binaryOperators = $binaryOperators;
|
||||
}
|
||||
|
||||
public function parseExpression($precedence = 0)
|
||||
{
|
||||
$expr = $this->getPrimary();
|
||||
$token = $this->parser->getCurrentToken();
|
||||
while ($this->isBinary($token) && $this->binaryOperators[$token->getValue()]['precedence'] >= $precedence) {
|
||||
$op = $this->binaryOperators[$token->getValue()];
|
||||
$this->parser->getStream()->next();
|
||||
|
||||
if (isset($op['callable'])) {
|
||||
$expr = call_user_func($op['callable'], $this->parser, $expr);
|
||||
} else {
|
||||
$expr1 = $this->parseExpression(self::OPERATOR_LEFT === $op['associativity'] ? $op['precedence'] + 1 : $op['precedence']);
|
||||
$class = $op['class'];
|
||||
$expr = new $class($expr, $expr1, $token->getLine());
|
||||
}
|
||||
|
||||
$token = $this->parser->getCurrentToken();
|
||||
}
|
||||
|
||||
if (0 === $precedence) {
|
||||
return $this->parseConditionalExpression($expr);
|
||||
}
|
||||
|
||||
return $expr;
|
||||
}
|
||||
|
||||
protected function getPrimary()
|
||||
{
|
||||
$token = $this->parser->getCurrentToken();
|
||||
|
||||
if ($this->isUnary($token)) {
|
||||
$operator = $this->unaryOperators[$token->getValue()];
|
||||
$this->parser->getStream()->next();
|
||||
$expr = $this->parseExpression($operator['precedence']);
|
||||
$class = $operator['class'];
|
||||
|
||||
return $this->parsePostfixExpression(new $class($expr, $token->getLine()));
|
||||
} elseif ($token->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
|
||||
$this->parser->getStream()->next();
|
||||
$expr = $this->parseExpression();
|
||||
$this->parser->getStream()->expect(Twig_Token::PUNCTUATION_TYPE, ')', 'An opened parenthesis is not properly closed');
|
||||
|
||||
return $this->parsePostfixExpression($expr);
|
||||
}
|
||||
|
||||
return $this->parsePrimaryExpression();
|
||||
}
|
||||
|
||||
protected function parseConditionalExpression($expr)
|
||||
{
|
||||
while ($this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, '?')) {
|
||||
$this->parser->getStream()->next();
|
||||
$expr2 = $this->parseExpression();
|
||||
$this->parser->getStream()->expect(Twig_Token::PUNCTUATION_TYPE, ':', 'The ternary operator must have a default value');
|
||||
$expr3 = $this->parseExpression();
|
||||
|
||||
$expr = new Twig_Node_Expression_Conditional($expr, $expr2, $expr3, $this->parser->getCurrentToken()->getLine());
|
||||
}
|
||||
|
||||
return $expr;
|
||||
}
|
||||
|
||||
protected function isUnary(Twig_Token $token)
|
||||
{
|
||||
return $token->test(Twig_Token::OPERATOR_TYPE) && isset($this->unaryOperators[$token->getValue()]);
|
||||
}
|
||||
|
||||
protected function isBinary(Twig_Token $token)
|
||||
{
|
||||
return $token->test(Twig_Token::OPERATOR_TYPE) && isset($this->binaryOperators[$token->getValue()]);
|
||||
}
|
||||
|
||||
public function parsePrimaryExpression()
|
||||
{
|
||||
$token = $this->parser->getCurrentToken();
|
||||
switch ($token->getType()) {
|
||||
case Twig_Token::NAME_TYPE:
|
||||
$this->parser->getStream()->next();
|
||||
switch ($token->getValue()) {
|
||||
case 'true':
|
||||
case 'TRUE':
|
||||
$node = new Twig_Node_Expression_Constant(true, $token->getLine());
|
||||
break;
|
||||
|
||||
case 'false':
|
||||
case 'FALSE':
|
||||
$node = new Twig_Node_Expression_Constant(false, $token->getLine());
|
||||
break;
|
||||
|
||||
case 'none':
|
||||
case 'NONE':
|
||||
case 'null':
|
||||
case 'NULL':
|
||||
$node = new Twig_Node_Expression_Constant(null, $token->getLine());
|
||||
break;
|
||||
|
||||
default:
|
||||
if ('(' === $this->parser->getCurrentToken()->getValue()) {
|
||||
$node = $this->getFunctionNode($token->getValue(), $token->getLine());
|
||||
} else {
|
||||
$node = new Twig_Node_Expression_Name($token->getValue(), $token->getLine());
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Twig_Token::NUMBER_TYPE:
|
||||
$this->parser->getStream()->next();
|
||||
$node = new Twig_Node_Expression_Constant($token->getValue(), $token->getLine());
|
||||
break;
|
||||
|
||||
case Twig_Token::STRING_TYPE:
|
||||
case Twig_Token::INTERPOLATION_START_TYPE:
|
||||
$node = $this->parseStringExpression();
|
||||
break;
|
||||
|
||||
default:
|
||||
if ($token->test(Twig_Token::PUNCTUATION_TYPE, '[')) {
|
||||
$node = $this->parseArrayExpression();
|
||||
} elseif ($token->test(Twig_Token::PUNCTUATION_TYPE, '{')) {
|
||||
$node = $this->parseHashExpression();
|
||||
} else {
|
||||
throw new Twig_Error_Syntax(sprintf('Unexpected token "%s" of value "%s"', Twig_Token::typeToEnglish($token->getType(), $token->getLine()), $token->getValue()), $token->getLine());
|
||||
}
|
||||
}
|
||||
|
||||
return $this->parsePostfixExpression($node);
|
||||
}
|
||||
|
||||
public function parseStringExpression()
|
||||
{
|
||||
$stream = $this->parser->getStream();
|
||||
|
||||
$nodes = array();
|
||||
// a string cannot be followed by another string in a single expression
|
||||
$nextCanBeString = true;
|
||||
while (true) {
|
||||
if ($stream->test(Twig_Token::STRING_TYPE) && $nextCanBeString) {
|
||||
$token = $stream->next();
|
||||
$nodes[] = new Twig_Node_Expression_Constant($token->getValue(), $token->getLine());
|
||||
$nextCanBeString = false;
|
||||
} elseif ($stream->test(Twig_Token::INTERPOLATION_START_TYPE)) {
|
||||
$stream->next();
|
||||
$nodes[] = $this->parseExpression();
|
||||
$stream->expect(Twig_Token::INTERPOLATION_END_TYPE);
|
||||
$nextCanBeString = true;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$expr = array_shift($nodes);
|
||||
foreach ($nodes as $node) {
|
||||
$expr = new Twig_Node_Expression_Binary_Concat($expr, $node, $node->getLine());
|
||||
}
|
||||
|
||||
return $expr;
|
||||
}
|
||||
|
||||
public function parseArrayExpression()
|
||||
{
|
||||
$stream = $this->parser->getStream();
|
||||
$stream->expect(Twig_Token::PUNCTUATION_TYPE, '[', 'An array element was expected');
|
||||
|
||||
$node = new Twig_Node_Expression_Array(array(), $stream->getCurrent()->getLine());
|
||||
$first = true;
|
||||
while (!$stream->test(Twig_Token::PUNCTUATION_TYPE, ']')) {
|
||||
if (!$first) {
|
||||
$stream->expect(Twig_Token::PUNCTUATION_TYPE, ',', 'An array element must be followed by a comma');
|
||||
|
||||
// trailing ,?
|
||||
if ($stream->test(Twig_Token::PUNCTUATION_TYPE, ']')) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
$first = false;
|
||||
|
||||
$node->addElement($this->parseExpression());
|
||||
}
|
||||
$stream->expect(Twig_Token::PUNCTUATION_TYPE, ']', 'An opened array is not properly closed');
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
public function parseHashExpression()
|
||||
{
|
||||
$stream = $this->parser->getStream();
|
||||
$stream->expect(Twig_Token::PUNCTUATION_TYPE, '{', 'A hash element was expected');
|
||||
|
||||
$node = new Twig_Node_Expression_Array(array(), $stream->getCurrent()->getLine());
|
||||
$first = true;
|
||||
while (!$stream->test(Twig_Token::PUNCTUATION_TYPE, '}')) {
|
||||
if (!$first) {
|
||||
$stream->expect(Twig_Token::PUNCTUATION_TYPE, ',', 'A hash value must be followed by a comma');
|
||||
|
||||
// trailing ,?
|
||||
if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '}')) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
$first = false;
|
||||
|
||||
// a hash key can be:
|
||||
//
|
||||
// * a number -- 12
|
||||
// * a string -- 'a'
|
||||
// * a name, which is equivalent to a string -- a
|
||||
// * an expression, which must be enclosed in parentheses -- (1 + 2)
|
||||
if ($stream->test(Twig_Token::STRING_TYPE) || $stream->test(Twig_Token::NAME_TYPE) || $stream->test(Twig_Token::NUMBER_TYPE)) {
|
||||
$token = $stream->next();
|
||||
$key = new Twig_Node_Expression_Constant($token->getValue(), $token->getLine());
|
||||
} elseif ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
|
||||
$key = $this->parseExpression();
|
||||
} else {
|
||||
$current = $stream->getCurrent();
|
||||
|
||||
throw new Twig_Error_Syntax(sprintf('A hash key must be a quoted string, a number, a name, or an expression enclosed in parentheses (unexpected token "%s" of value "%s"', Twig_Token::typeToEnglish($current->getType(), $current->getLine()), $current->getValue()), $current->getLine());
|
||||
}
|
||||
|
||||
$stream->expect(Twig_Token::PUNCTUATION_TYPE, ':', 'A hash key must be followed by a colon (:)');
|
||||
$value = $this->parseExpression();
|
||||
|
||||
$node->addElement($value, $key);
|
||||
}
|
||||
$stream->expect(Twig_Token::PUNCTUATION_TYPE, '}', 'An opened hash is not properly closed');
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
public function parsePostfixExpression($node)
|
||||
{
|
||||
while (true) {
|
||||
$token = $this->parser->getCurrentToken();
|
||||
if ($token->getType() == Twig_Token::PUNCTUATION_TYPE) {
|
||||
if ('.' == $token->getValue() || '[' == $token->getValue()) {
|
||||
$node = $this->parseSubscriptExpression($node);
|
||||
} elseif ('|' == $token->getValue()) {
|
||||
$node = $this->parseFilterExpression($node);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
public function getFunctionNode($name, $line)
|
||||
{
|
||||
$args = $this->parseArguments();
|
||||
switch ($name) {
|
||||
case 'parent':
|
||||
if (!count($this->parser->getBlockStack())) {
|
||||
throw new Twig_Error_Syntax('Calling "parent" outside a block is forbidden', $line);
|
||||
}
|
||||
|
||||
if (!$this->parser->getParent() && !$this->parser->hasTraits()) {
|
||||
throw new Twig_Error_Syntax('Calling "parent" on a template that does not extend nor "use" another template is forbidden', $line);
|
||||
}
|
||||
|
||||
return new Twig_Node_Expression_Parent($this->parser->peekBlockStack(), $line);
|
||||
case 'block':
|
||||
return new Twig_Node_Expression_BlockReference($args->getNode(0), false, $line);
|
||||
case 'attribute':
|
||||
if (count($args) < 2) {
|
||||
throw new Twig_Error_Syntax('The "attribute" function takes at least two arguments (the variable and the attributes)', $line);
|
||||
}
|
||||
|
||||
return new Twig_Node_Expression_GetAttr($args->getNode(0), $args->getNode(1), count($args) > 2 ? $args->getNode(2) : new Twig_Node_Expression_Array(array(), $line), Twig_TemplateInterface::ANY_CALL, $line);
|
||||
default:
|
||||
if (null !== $alias = $this->parser->getImportedFunction($name)) {
|
||||
$arguments = new Twig_Node_Expression_Array(array(), $line);
|
||||
foreach ($args as $n) {
|
||||
$arguments->addElement($n);
|
||||
}
|
||||
|
||||
$node = new Twig_Node_Expression_MethodCall($alias['node'], $alias['name'], $arguments, $line);
|
||||
$node->setAttribute('safe', true);
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
$class = $this->getFunctionNodeClass($name);
|
||||
|
||||
return new $class($name, $args, $line);
|
||||
}
|
||||
}
|
||||
|
||||
public function parseSubscriptExpression($node)
|
||||
{
|
||||
$stream = $this->parser->getStream();
|
||||
$token = $stream->next();
|
||||
$lineno = $token->getLine();
|
||||
$arguments = new Twig_Node_Expression_Array(array(), $lineno);
|
||||
$type = Twig_TemplateInterface::ANY_CALL;
|
||||
if ($token->getValue() == '.') {
|
||||
$token = $stream->next();
|
||||
if (
|
||||
$token->getType() == Twig_Token::NAME_TYPE
|
||||
||
|
||||
$token->getType() == Twig_Token::NUMBER_TYPE
|
||||
||
|
||||
($token->getType() == Twig_Token::OPERATOR_TYPE && preg_match(Twig_Lexer::REGEX_NAME, $token->getValue()))
|
||||
) {
|
||||
$arg = new Twig_Node_Expression_Constant($token->getValue(), $lineno);
|
||||
|
||||
if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
|
||||
$type = Twig_TemplateInterface::METHOD_CALL;
|
||||
foreach ($this->parseArguments() as $n) {
|
||||
$arguments->addElement($n);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new Twig_Error_Syntax('Expected name or number', $lineno);
|
||||
}
|
||||
} else {
|
||||
$type = Twig_TemplateInterface::ARRAY_CALL;
|
||||
|
||||
$arg = $this->parseExpression();
|
||||
|
||||
// slice?
|
||||
if ($stream->test(Twig_Token::PUNCTUATION_TYPE, ':')) {
|
||||
$stream->next();
|
||||
|
||||
if ($stream->test(Twig_Token::PUNCTUATION_TYPE, ']')) {
|
||||
$length = new Twig_Node_Expression_Constant(null, $token->getLine());
|
||||
} else {
|
||||
$length = $this->parseExpression();
|
||||
}
|
||||
|
||||
$class = $this->getFilterNodeClass('slice');
|
||||
$arguments = new Twig_Node(array($arg, $length));
|
||||
$filter = new $class($node, new Twig_Node_Expression_Constant('slice', $token->getLine()), $arguments, $token->getLine());
|
||||
|
||||
$stream->expect(Twig_Token::PUNCTUATION_TYPE, ']');
|
||||
|
||||
return $filter;
|
||||
}
|
||||
|
||||
$stream->expect(Twig_Token::PUNCTUATION_TYPE, ']');
|
||||
}
|
||||
|
||||
return new Twig_Node_Expression_GetAttr($node, $arg, $arguments, $type, $lineno);
|
||||
}
|
||||
|
||||
public function parseFilterExpression($node)
|
||||
{
|
||||
$this->parser->getStream()->next();
|
||||
|
||||
return $this->parseFilterExpressionRaw($node);
|
||||
}
|
||||
|
||||
public function parseFilterExpressionRaw($node, $tag = null)
|
||||
{
|
||||
while (true) {
|
||||
$token = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE);
|
||||
|
||||
$name = new Twig_Node_Expression_Constant($token->getValue(), $token->getLine());
|
||||
if (!$this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
|
||||
$arguments = new Twig_Node();
|
||||
} else {
|
||||
$arguments = $this->parseArguments();
|
||||
}
|
||||
|
||||
$class = $this->getFilterNodeClass($name->getAttribute('value'));
|
||||
|
||||
$node = new $class($node, $name, $arguments, $token->getLine(), $tag);
|
||||
|
||||
if (!$this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, '|')) {
|
||||
break;
|
||||
}
|
||||
|
||||
$this->parser->getStream()->next();
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
public function parseArguments()
|
||||
{
|
||||
$args = array();
|
||||
$stream = $this->parser->getStream();
|
||||
|
||||
$stream->expect(Twig_Token::PUNCTUATION_TYPE, '(', 'A list of arguments must be opened by a parenthesis');
|
||||
while (!$stream->test(Twig_Token::PUNCTUATION_TYPE, ')')) {
|
||||
if (!empty($args)) {
|
||||
$stream->expect(Twig_Token::PUNCTUATION_TYPE, ',', 'Arguments must be separated by a comma');
|
||||
}
|
||||
$args[] = $this->parseExpression();
|
||||
}
|
||||
$stream->expect(Twig_Token::PUNCTUATION_TYPE, ')', 'A list of arguments must be closed by a parenthesis');
|
||||
|
||||
return new Twig_Node($args);
|
||||
}
|
||||
|
||||
public function parseAssignmentExpression()
|
||||
{
|
||||
$targets = array();
|
||||
while (true) {
|
||||
$token = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE, null, 'Only variables can be assigned to');
|
||||
if (in_array($token->getValue(), array('true', 'false', 'none'))) {
|
||||
throw new Twig_Error_Syntax(sprintf('You cannot assign a value to "%s"', $token->getValue()), $token->getLine());
|
||||
}
|
||||
$targets[] = new Twig_Node_Expression_AssignName($token->getValue(), $token->getLine());
|
||||
|
||||
if (!$this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, ',')) {
|
||||
break;
|
||||
}
|
||||
$this->parser->getStream()->next();
|
||||
}
|
||||
|
||||
return new Twig_Node($targets);
|
||||
}
|
||||
|
||||
public function parseMultitargetExpression()
|
||||
{
|
||||
$targets = array();
|
||||
while (true) {
|
||||
$targets[] = $this->parseExpression();
|
||||
if (!$this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, ',')) {
|
||||
break;
|
||||
}
|
||||
$this->parser->getStream()->next();
|
||||
}
|
||||
|
||||
return new Twig_Node($targets);
|
||||
}
|
||||
|
||||
protected function getFunctionNodeClass($name)
|
||||
{
|
||||
$functionMap = $this->parser->getEnvironment()->getFunctions();
|
||||
if (isset($functionMap[$name]) && $functionMap[$name] instanceof Twig_Function_Node) {
|
||||
return $functionMap[$name]->getClass();
|
||||
}
|
||||
|
||||
return 'Twig_Node_Expression_Function';
|
||||
}
|
||||
|
||||
protected function getFilterNodeClass($name)
|
||||
{
|
||||
$filterMap = $this->parser->getEnvironment()->getFilters();
|
||||
if (isset($filterMap[$name]) && $filterMap[$name] instanceof Twig_Filter_Node) {
|
||||
return $filterMap[$name]->getClass();
|
||||
}
|
||||
|
||||
return 'Twig_Node_Expression_Filter';
|
||||
}
|
||||
}
|
93
Core/Frameworks/Flake/Util/Twig/lib/Twig/Extension.php
Normal file
93
Core/Frameworks/Flake/Util/Twig/lib/Twig/Extension.php
Normal file
|
@ -0,0 +1,93 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
abstract class Twig_Extension implements Twig_ExtensionInterface
|
||||
{
|
||||
/**
|
||||
* Initializes the runtime environment.
|
||||
*
|
||||
* This is where you can load some file that contains filter functions for instance.
|
||||
*
|
||||
* @param Twig_Environment $environment The current Twig_Environment instance
|
||||
*/
|
||||
public function initRuntime(Twig_Environment $environment)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the token parser instances to add to the existing list.
|
||||
*
|
||||
* @return array An array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances
|
||||
*/
|
||||
public function getTokenParsers()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the node visitor instances to add to the existing list.
|
||||
*
|
||||
* @return array An array of Twig_NodeVisitorInterface instances
|
||||
*/
|
||||
public function getNodeVisitors()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of filters to add to the existing list.
|
||||
*
|
||||
* @return array An array of filters
|
||||
*/
|
||||
public function getFilters()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of tests to add to the existing list.
|
||||
*
|
||||
* @return array An array of tests
|
||||
*/
|
||||
public function getTests()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of functions to add to the existing list.
|
||||
*
|
||||
* @return array An array of functions
|
||||
*/
|
||||
public function getFunctions()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of operators to add to the existing list.
|
||||
*
|
||||
* @return array An array of operators
|
||||
*/
|
||||
public function getOperators()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of global variables to add to the existing list.
|
||||
*
|
||||
* @return array An array of global variables
|
||||
*/
|
||||
public function getGlobals()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
}
|
1037
Core/Frameworks/Flake/Util/Twig/lib/Twig/Extension/Core.php
Normal file
1037
Core/Frameworks/Flake/Util/Twig/lib/Twig/Extension/Core.php
Normal file
File diff suppressed because it is too large
Load diff
64
Core/Frameworks/Flake/Util/Twig/lib/Twig/Extension/Debug.php
Normal file
64
Core/Frameworks/Flake/Util/Twig/lib/Twig/Extension/Debug.php
Normal file
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2011 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Extension_Debug extends Twig_Extension
|
||||
{
|
||||
/**
|
||||
* Returns a list of global functions to add to the existing list.
|
||||
*
|
||||
* @return array An array of global functions
|
||||
*/
|
||||
public function getFunctions()
|
||||
{
|
||||
// dump is safe if var_dump is overriden by xdebug
|
||||
$isDumpOutputHtmlSafe = extension_loaded('xdebug') && (false === get_cfg_var('xdebug.overload_var_dump') || get_cfg_var('xdebug.overload_var_dump')) && get_cfg_var('html_errors');
|
||||
|
||||
return array(
|
||||
'dump' => new Twig_Function_Function('twig_var_dump', array('is_safe' => $isDumpOutputHtmlSafe ? array('html') : array(), 'needs_context' => true, 'needs_environment' => true)),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the extension.
|
||||
*
|
||||
* @return string The extension name
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'debug';
|
||||
}
|
||||
}
|
||||
|
||||
function twig_var_dump(Twig_Environment $env, $context)
|
||||
{
|
||||
if (!$env->isDebug()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ob_start();
|
||||
|
||||
$count = func_num_args();
|
||||
if (2 === $count) {
|
||||
$vars = array();
|
||||
foreach ($context as $key => $value) {
|
||||
if (!$value instanceof Twig_Template) {
|
||||
$vars[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
var_dump($vars);
|
||||
} else {
|
||||
for ($i = 2; $i < $count; $i++) {
|
||||
var_dump(func_get_arg($i));
|
||||
}
|
||||
}
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
106
Core/Frameworks/Flake/Util/Twig/lib/Twig/Extension/Escaper.php
Normal file
106
Core/Frameworks/Flake/Util/Twig/lib/Twig/Extension/Escaper.php
Normal file
|
@ -0,0 +1,106 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Extension_Escaper extends Twig_Extension
|
||||
{
|
||||
protected $defaultStrategy;
|
||||
|
||||
public function __construct($defaultStrategy = 'html')
|
||||
{
|
||||
$this->setDefaultStrategy($defaultStrategy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the token parser instances to add to the existing list.
|
||||
*
|
||||
* @return array An array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances
|
||||
*/
|
||||
public function getTokenParsers()
|
||||
{
|
||||
return array(new Twig_TokenParser_AutoEscape());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the node visitor instances to add to the existing list.
|
||||
*
|
||||
* @return array An array of Twig_NodeVisitorInterface instances
|
||||
*/
|
||||
public function getNodeVisitors()
|
||||
{
|
||||
return array(new Twig_NodeVisitor_Escaper());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of filters to add to the existing list.
|
||||
*
|
||||
* @return array An array of filters
|
||||
*/
|
||||
public function getFilters()
|
||||
{
|
||||
return array(
|
||||
'raw' => new Twig_Filter_Function('twig_raw_filter', array('is_safe' => array('all'))),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the default strategy to use when not defined by the user.
|
||||
*
|
||||
* The strategy can be a valid PHP callback that takes the template
|
||||
* "filename" as an argument and returns the strategy to use.
|
||||
*
|
||||
* @param mixed $defaultStrategy An escaping strategy
|
||||
*/
|
||||
public function setDefaultStrategy($defaultStrategy)
|
||||
{
|
||||
// for BC
|
||||
if (true === $defaultStrategy) {
|
||||
$defaultStrategy = 'html';
|
||||
}
|
||||
|
||||
$this->defaultStrategy = $defaultStrategy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default strategy to use when not defined by the user.
|
||||
*
|
||||
* @param string $filename The template "filename"
|
||||
*
|
||||
* @return string The default strategy to use for the template
|
||||
*/
|
||||
public function getDefaultStrategy($filename)
|
||||
{
|
||||
if (is_callable($this->defaultStrategy)) {
|
||||
return call_user_func($this->defaultStrategy, $filename);
|
||||
}
|
||||
|
||||
return $this->defaultStrategy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the extension.
|
||||
*
|
||||
* @return string The extension name
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'escaper';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks a variable as being safe.
|
||||
*
|
||||
* @param string $string A PHP variable
|
||||
*/
|
||||
function twig_raw_filter($string)
|
||||
{
|
||||
return $string;
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Extension_Optimizer extends Twig_Extension
|
||||
{
|
||||
protected $optimizers;
|
||||
|
||||
public function __construct($optimizers = -1)
|
||||
{
|
||||
$this->optimizers = $optimizers;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getNodeVisitors()
|
||||
{
|
||||
return array(new Twig_NodeVisitor_Optimizer($this->optimizers));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'optimizer';
|
||||
}
|
||||
}
|
112
Core/Frameworks/Flake/Util/Twig/lib/Twig/Extension/Sandbox.php
Normal file
112
Core/Frameworks/Flake/Util/Twig/lib/Twig/Extension/Sandbox.php
Normal file
|
@ -0,0 +1,112 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Extension_Sandbox extends Twig_Extension
|
||||
{
|
||||
protected $sandboxedGlobally;
|
||||
protected $sandboxed;
|
||||
protected $policy;
|
||||
|
||||
public function __construct(Twig_Sandbox_SecurityPolicyInterface $policy, $sandboxed = false)
|
||||
{
|
||||
$this->policy = $policy;
|
||||
$this->sandboxedGlobally = $sandboxed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the token parser instances to add to the existing list.
|
||||
*
|
||||
* @return array An array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances
|
||||
*/
|
||||
public function getTokenParsers()
|
||||
{
|
||||
return array(new Twig_TokenParser_Sandbox());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the node visitor instances to add to the existing list.
|
||||
*
|
||||
* @return array An array of Twig_NodeVisitorInterface instances
|
||||
*/
|
||||
public function getNodeVisitors()
|
||||
{
|
||||
return array(new Twig_NodeVisitor_Sandbox());
|
||||
}
|
||||
|
||||
public function enableSandbox()
|
||||
{
|
||||
$this->sandboxed = true;
|
||||
}
|
||||
|
||||
public function disableSandbox()
|
||||
{
|
||||
$this->sandboxed = false;
|
||||
}
|
||||
|
||||
public function isSandboxed()
|
||||
{
|
||||
return $this->sandboxedGlobally || $this->sandboxed;
|
||||
}
|
||||
|
||||
public function isSandboxedGlobally()
|
||||
{
|
||||
return $this->sandboxedGlobally;
|
||||
}
|
||||
|
||||
public function setSecurityPolicy(Twig_Sandbox_SecurityPolicyInterface $policy)
|
||||
{
|
||||
$this->policy = $policy;
|
||||
}
|
||||
|
||||
public function getSecurityPolicy()
|
||||
{
|
||||
return $this->policy;
|
||||
}
|
||||
|
||||
public function checkSecurity($tags, $filters, $functions)
|
||||
{
|
||||
if ($this->isSandboxed()) {
|
||||
$this->policy->checkSecurity($tags, $filters, $functions);
|
||||
}
|
||||
}
|
||||
|
||||
public function checkMethodAllowed($obj, $method)
|
||||
{
|
||||
if ($this->isSandboxed()) {
|
||||
$this->policy->checkMethodAllowed($obj, $method);
|
||||
}
|
||||
}
|
||||
|
||||
public function checkPropertyAllowed($obj, $method)
|
||||
{
|
||||
if ($this->isSandboxed()) {
|
||||
$this->policy->checkPropertyAllowed($obj, $method);
|
||||
}
|
||||
}
|
||||
|
||||
public function ensureToStringAllowed($obj)
|
||||
{
|
||||
if (is_object($obj)) {
|
||||
$this->policy->checkMethodAllowed($obj, '__toString');
|
||||
}
|
||||
|
||||
return $obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the extension.
|
||||
*
|
||||
* @return string The extension name
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'sandbox';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Interface implemented by extension classes.
|
||||
*
|
||||
* @package twig
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
interface Twig_ExtensionInterface
|
||||
{
|
||||
/**
|
||||
* Initializes the runtime environment.
|
||||
*
|
||||
* This is where you can load some file that contains filter functions for instance.
|
||||
*
|
||||
* @param Twig_Environment $environment The current Twig_Environment instance
|
||||
*/
|
||||
function initRuntime(Twig_Environment $environment);
|
||||
|
||||
/**
|
||||
* Returns the token parser instances to add to the existing list.
|
||||
*
|
||||
* @return array An array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances
|
||||
*/
|
||||
function getTokenParsers();
|
||||
|
||||
/**
|
||||
* Returns the node visitor instances to add to the existing list.
|
||||
*
|
||||
* @return array An array of Twig_NodeVisitorInterface instances
|
||||
*/
|
||||
function getNodeVisitors();
|
||||
|
||||
/**
|
||||
* Returns a list of filters to add to the existing list.
|
||||
*
|
||||
* @return array An array of filters
|
||||
*/
|
||||
function getFilters();
|
||||
|
||||
/**
|
||||
* Returns a list of tests to add to the existing list.
|
||||
*
|
||||
* @return array An array of tests
|
||||
*/
|
||||
function getTests();
|
||||
|
||||
/**
|
||||
* Returns a list of functions to add to the existing list.
|
||||
*
|
||||
* @return array An array of functions
|
||||
*/
|
||||
function getFunctions();
|
||||
|
||||
/**
|
||||
* Returns a list of operators to add to the existing list.
|
||||
*
|
||||
* @return array An array of operators
|
||||
*/
|
||||
function getOperators();
|
||||
|
||||
/**
|
||||
* Returns a list of global variables to add to the existing list.
|
||||
*
|
||||
* @return array An array of global variables
|
||||
*/
|
||||
function getGlobals();
|
||||
|
||||
/**
|
||||
* Returns the name of the extension.
|
||||
*
|
||||
* @return string The extension name
|
||||
*/
|
||||
function getName();
|
||||
}
|
75
Core/Frameworks/Flake/Util/Twig/lib/Twig/Filter.php
Normal file
75
Core/Frameworks/Flake/Util/Twig/lib/Twig/Filter.php
Normal file
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a template filter.
|
||||
*
|
||||
* @package twig
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
abstract class Twig_Filter implements Twig_FilterInterface
|
||||
{
|
||||
protected $options;
|
||||
protected $arguments = array();
|
||||
|
||||
public function __construct(array $options = array())
|
||||
{
|
||||
$this->options = array_merge(array(
|
||||
'needs_environment' => false,
|
||||
'needs_context' => false,
|
||||
'pre_escape' => null,
|
||||
'preserves_safety' => null,
|
||||
), $options);
|
||||
}
|
||||
|
||||
public function setArguments($arguments)
|
||||
{
|
||||
$this->arguments = $arguments;
|
||||
}
|
||||
|
||||
public function getArguments()
|
||||
{
|
||||
return $this->arguments;
|
||||
}
|
||||
|
||||
public function needsEnvironment()
|
||||
{
|
||||
return $this->options['needs_environment'];
|
||||
}
|
||||
|
||||
public function needsContext()
|
||||
{
|
||||
return $this->options['needs_context'];
|
||||
}
|
||||
|
||||
public function getSafe(Twig_Node $filterArgs)
|
||||
{
|
||||
if (isset($this->options['is_safe'])) {
|
||||
return $this->options['is_safe'];
|
||||
}
|
||||
|
||||
if (isset($this->options['is_safe_callback'])) {
|
||||
return call_user_func($this->options['is_safe_callback'], $filterArgs);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getPreservesSafety()
|
||||
{
|
||||
return $this->options['preserves_safety'];
|
||||
}
|
||||
|
||||
public function getPreEscape()
|
||||
{
|
||||
return $this->options['pre_escape'];
|
||||
}
|
||||
}
|
33
Core/Frameworks/Flake/Util/Twig/lib/Twig/Filter/Function.php
Normal file
33
Core/Frameworks/Flake/Util/Twig/lib/Twig/Filter/Function.php
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a function template filter.
|
||||
*
|
||||
* @package twig
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Filter_Function extends Twig_Filter
|
||||
{
|
||||
protected $function;
|
||||
|
||||
public function __construct($function, array $options = array())
|
||||
{
|
||||
parent::__construct($options);
|
||||
|
||||
$this->function = $function;
|
||||
}
|
||||
|
||||
public function compile()
|
||||
{
|
||||
return $this->function;
|
||||
}
|
||||
}
|
34
Core/Frameworks/Flake/Util/Twig/lib/Twig/Filter/Method.php
Normal file
34
Core/Frameworks/Flake/Util/Twig/lib/Twig/Filter/Method.php
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a method template filter.
|
||||
*
|
||||
* @package twig
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Filter_Method extends Twig_Filter
|
||||
{
|
||||
protected $extension, $method;
|
||||
|
||||
public function __construct(Twig_ExtensionInterface $extension, $method, array $options = array())
|
||||
{
|
||||
parent::__construct($options);
|
||||
|
||||
$this->extension = $extension;
|
||||
$this->method = $method;
|
||||
}
|
||||
|
||||
public function compile()
|
||||
{
|
||||
return sprintf('$this->env->getExtension(\'%s\')->%s', $this->extension->getName(), $this->method);
|
||||
}
|
||||
}
|
37
Core/Frameworks/Flake/Util/Twig/lib/Twig/Filter/Node.php
Normal file
37
Core/Frameworks/Flake/Util/Twig/lib/Twig/Filter/Node.php
Normal file
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2011 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a template filter as a node.
|
||||
*
|
||||
* @package twig
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Filter_Node extends Twig_Filter
|
||||
{
|
||||
protected $class;
|
||||
|
||||
public function __construct($class, array $options = array())
|
||||
{
|
||||
parent::__construct($options);
|
||||
|
||||
$this->class = $class;
|
||||
}
|
||||
|
||||
public function getClass()
|
||||
{
|
||||
return $this->class;
|
||||
}
|
||||
|
||||
public function compile()
|
||||
{
|
||||
}
|
||||
}
|
40
Core/Frameworks/Flake/Util/Twig/lib/Twig/FilterInterface.php
Normal file
40
Core/Frameworks/Flake/Util/Twig/lib/Twig/FilterInterface.php
Normal file
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a template filter.
|
||||
*
|
||||
* @package twig
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
interface Twig_FilterInterface
|
||||
{
|
||||
/**
|
||||
* Compiles a filter.
|
||||
*
|
||||
* @return string The PHP code for the filter
|
||||
*/
|
||||
function compile();
|
||||
|
||||
function needsEnvironment();
|
||||
|
||||
function needsContext();
|
||||
|
||||
function getSafe(Twig_Node $filterArgs);
|
||||
|
||||
function getPreservesSafety();
|
||||
|
||||
function getPreEscape();
|
||||
|
||||
function setArguments($arguments);
|
||||
|
||||
function getArguments();
|
||||
}
|
63
Core/Frameworks/Flake/Util/Twig/lib/Twig/Function.php
Normal file
63
Core/Frameworks/Flake/Util/Twig/lib/Twig/Function.php
Normal file
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a template function.
|
||||
*
|
||||
* @package twig
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
abstract class Twig_Function implements Twig_FunctionInterface
|
||||
{
|
||||
protected $options;
|
||||
protected $arguments = array();
|
||||
|
||||
public function __construct(array $options = array())
|
||||
{
|
||||
$this->options = array_merge(array(
|
||||
'needs_environment' => false,
|
||||
'needs_context' => false,
|
||||
), $options);
|
||||
}
|
||||
|
||||
public function setArguments($arguments)
|
||||
{
|
||||
$this->arguments = $arguments;
|
||||
}
|
||||
|
||||
public function getArguments()
|
||||
{
|
||||
return $this->arguments;
|
||||
}
|
||||
|
||||
public function needsEnvironment()
|
||||
{
|
||||
return $this->options['needs_environment'];
|
||||
}
|
||||
|
||||
public function needsContext()
|
||||
{
|
||||
return $this->options['needs_context'];
|
||||
}
|
||||
|
||||
public function getSafe(Twig_Node $functionArgs)
|
||||
{
|
||||
if (isset($this->options['is_safe'])) {
|
||||
return $this->options['is_safe'];
|
||||
}
|
||||
|
||||
if (isset($this->options['is_safe_callback'])) {
|
||||
return call_user_func($this->options['is_safe_callback'], $functionArgs);
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2010 Arnaud Le Blanc
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a function template function.
|
||||
*
|
||||
* @package twig
|
||||
* @author Arnaud Le Blanc <arnaud.lb@gmail.com>
|
||||
*/
|
||||
class Twig_Function_Function extends Twig_Function
|
||||
{
|
||||
protected $function;
|
||||
|
||||
public function __construct($function, array $options = array())
|
||||
{
|
||||
parent::__construct($options);
|
||||
|
||||
$this->function = $function;
|
||||
}
|
||||
|
||||
public function compile()
|
||||
{
|
||||
return $this->function;
|
||||
}
|
||||
}
|
35
Core/Frameworks/Flake/Util/Twig/lib/Twig/Function/Method.php
Normal file
35
Core/Frameworks/Flake/Util/Twig/lib/Twig/Function/Method.php
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2010 Arnaud Le Blanc
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a method template function.
|
||||
*
|
||||
* @package twig
|
||||
* @author Arnaud Le Blanc <arnaud.lb@gmail.com>
|
||||
*/
|
||||
class Twig_Function_Method extends Twig_Function
|
||||
{
|
||||
protected $extension, $method;
|
||||
|
||||
public function __construct(Twig_ExtensionInterface $extension, $method, array $options = array())
|
||||
{
|
||||
parent::__construct($options);
|
||||
|
||||
$this->extension = $extension;
|
||||
$this->method = $method;
|
||||
}
|
||||
|
||||
public function compile()
|
||||
{
|
||||
return sprintf('$this->env->getExtension(\'%s\')->%s', $this->extension->getName(), $this->method);
|
||||
}
|
||||
}
|
37
Core/Frameworks/Flake/Util/Twig/lib/Twig/Function/Node.php
Normal file
37
Core/Frameworks/Flake/Util/Twig/lib/Twig/Function/Node.php
Normal file
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2011 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a template function as a node.
|
||||
*
|
||||
* @package twig
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Function_Node extends Twig_Filter
|
||||
{
|
||||
protected $class;
|
||||
|
||||
public function __construct($class, array $options = array())
|
||||
{
|
||||
parent::__construct($options);
|
||||
|
||||
$this->class = $class;
|
||||
}
|
||||
|
||||
public function getClass()
|
||||
{
|
||||
return $this->class;
|
||||
}
|
||||
|
||||
public function compile()
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
* (c) 2010 Arnaud Le Blanc
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a template function.
|
||||
*
|
||||
* @package twig
|
||||
* @author Arnaud Le Blanc <arnaud.lb@gmail.com>
|
||||
*/
|
||||
interface Twig_FunctionInterface
|
||||
{
|
||||
/**
|
||||
* Compiles a function.
|
||||
*
|
||||
* @return string The PHP code for the function
|
||||
*/
|
||||
function compile();
|
||||
|
||||
function needsEnvironment();
|
||||
|
||||
function needsContext();
|
||||
|
||||
function getSafe(Twig_Node $filterArgs);
|
||||
|
||||
function setArguments($arguments);
|
||||
|
||||
function getArguments();
|
||||
}
|
406
Core/Frameworks/Flake/Util/Twig/lib/Twig/Lexer.php
Normal file
406
Core/Frameworks/Flake/Util/Twig/lib/Twig/Lexer.php
Normal file
|
@ -0,0 +1,406 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Lexes a template string.
|
||||
*
|
||||
* @package twig
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Lexer implements Twig_LexerInterface
|
||||
{
|
||||
protected $tokens;
|
||||
protected $code;
|
||||
protected $cursor;
|
||||
protected $lineno;
|
||||
protected $end;
|
||||
protected $state;
|
||||
protected $states;
|
||||
protected $brackets;
|
||||
protected $env;
|
||||
protected $filename;
|
||||
protected $options;
|
||||
protected $regexes;
|
||||
|
||||
const STATE_DATA = 0;
|
||||
const STATE_BLOCK = 1;
|
||||
const STATE_VAR = 2;
|
||||
const STATE_STRING = 3;
|
||||
const STATE_INTERPOLATION = 4;
|
||||
|
||||
const REGEX_NAME = '/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/A';
|
||||
const REGEX_NUMBER = '/[0-9]+(?:\.[0-9]+)?/A';
|
||||
const REGEX_STRING = '/"([^#"\\\\]*(?:\\\\.[^#"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\'/As';
|
||||
const REGEX_DQ_STRING_DELIM = '/"/A';
|
||||
const REGEX_DQ_STRING_PART = '/[^#"\\\\]*(?:(?:\\\\.|#(?!\{))[^#"\\\\]*)*/As';
|
||||
const PUNCTUATION = '()[]{}?:.,|';
|
||||
|
||||
public function __construct(Twig_Environment $env, array $options = array())
|
||||
{
|
||||
$this->env = $env;
|
||||
|
||||
$this->options = array_merge(array(
|
||||
'tag_comment' => array('{#', '#}'),
|
||||
'tag_block' => array('{%', '%}'),
|
||||
'tag_variable' => array('{{', '}}'),
|
||||
'whitespace_trim' => '-',
|
||||
'interpolation' => array('#{', '}'),
|
||||
), $options);
|
||||
|
||||
$this->regexes = array(
|
||||
'lex_var' => '/\s*'.preg_quote($this->options['whitespace_trim'].$this->options['tag_variable'][1], '/').'\s*|\s*'.preg_quote($this->options['tag_variable'][1], '/').'/A',
|
||||
'lex_block' => '/\s*(?:'.preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '/').'\s*|\s*'.preg_quote($this->options['tag_block'][1], '/').')\n?/A',
|
||||
'lex_raw_data' => '/('.preg_quote($this->options['tag_block'][0].$this->options['whitespace_trim'], '/').'|'.preg_quote($this->options['tag_block'][0], '/').')\s*endraw\s*(?:'.preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '/').'\s*|\s*'.preg_quote($this->options['tag_block'][1], '/').')/s',
|
||||
'operator' => $this->getOperatorRegex(),
|
||||
'lex_comment' => '/(?:'.preg_quote($this->options['whitespace_trim'], '/').preg_quote($this->options['tag_comment'][1], '/').'\s*|'.preg_quote($this->options['tag_comment'][1], '/').')\n?/s',
|
||||
'lex_block_raw' => '/\s*raw\s*(?:'.preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '/').'\s*|\s*'.preg_quote($this->options['tag_block'][1], '/').')/As',
|
||||
'lex_block_line' => '/\s*line\s+(\d+)\s*'.preg_quote($this->options['tag_block'][1], '/').'/As',
|
||||
'lex_tokens_start' => '/('.preg_quote($this->options['tag_variable'][0], '/').'|'.preg_quote($this->options['tag_block'][0], '/').'|'.preg_quote($this->options['tag_comment'][0], '/').')('.preg_quote($this->options['whitespace_trim'], '/').')?/s',
|
||||
'interpolation_start' => '/'.preg_quote($this->options['interpolation'][0], '/').'\s*/A',
|
||||
'interpolation_end' => '/\s*'.preg_quote($this->options['interpolation'][1], '/').'/A',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tokenizes a source code.
|
||||
*
|
||||
* @param string $code The source code
|
||||
* @param string $filename A unique identifier for the source code
|
||||
*
|
||||
* @return Twig_TokenStream A token stream instance
|
||||
*/
|
||||
public function tokenize($code, $filename = null)
|
||||
{
|
||||
if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) {
|
||||
$mbEncoding = mb_internal_encoding();
|
||||
mb_internal_encoding('ASCII');
|
||||
}
|
||||
|
||||
$this->code = str_replace(array("\r\n", "\r"), "\n", $code);
|
||||
$this->filename = $filename;
|
||||
$this->cursor = 0;
|
||||
$this->lineno = 1;
|
||||
$this->end = strlen($this->code);
|
||||
$this->tokens = array();
|
||||
$this->state = self::STATE_DATA;
|
||||
$this->states = array();
|
||||
$this->brackets = array();
|
||||
$this->position = -1;
|
||||
|
||||
// find all token starts in one go
|
||||
preg_match_all($this->regexes['lex_tokens_start'], $this->code, $matches, PREG_OFFSET_CAPTURE);
|
||||
$this->positions = $matches;
|
||||
|
||||
while ($this->cursor < $this->end) {
|
||||
// dispatch to the lexing functions depending
|
||||
// on the current state
|
||||
switch ($this->state) {
|
||||
case self::STATE_DATA:
|
||||
$this->lexData();
|
||||
break;
|
||||
|
||||
case self::STATE_BLOCK:
|
||||
$this->lexBlock();
|
||||
break;
|
||||
|
||||
case self::STATE_VAR:
|
||||
$this->lexVar();
|
||||
break;
|
||||
|
||||
case self::STATE_STRING:
|
||||
$this->lexString();
|
||||
break;
|
||||
|
||||
case self::STATE_INTERPOLATION:
|
||||
$this->lexInterpolation();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$this->pushToken(Twig_Token::EOF_TYPE);
|
||||
|
||||
if (!empty($this->brackets)) {
|
||||
list($expect, $lineno) = array_pop($this->brackets);
|
||||
throw new Twig_Error_Syntax(sprintf('Unclosed "%s"', $expect), $lineno, $this->filename);
|
||||
}
|
||||
|
||||
if (isset($mbEncoding)) {
|
||||
mb_internal_encoding($mbEncoding);
|
||||
}
|
||||
|
||||
return new Twig_TokenStream($this->tokens, $this->filename);
|
||||
}
|
||||
|
||||
protected function lexData()
|
||||
{
|
||||
// if no matches are left we return the rest of the template as simple text token
|
||||
if ($this->position == count($this->positions[0]) - 1) {
|
||||
$this->pushToken(Twig_Token::TEXT_TYPE, substr($this->code, $this->cursor));
|
||||
$this->cursor = $this->end;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the first token after the current cursor
|
||||
$position = $this->positions[0][++$this->position];
|
||||
while ($position[1] < $this->cursor) {
|
||||
if ($this->position == count($this->positions[0]) - 1) {
|
||||
return;
|
||||
}
|
||||
$position = $this->positions[0][++$this->position];
|
||||
}
|
||||
|
||||
// push the template text first
|
||||
$text = $textContent = substr($this->code, $this->cursor, $position[1] - $this->cursor);
|
||||
if (isset($this->positions[2][$this->position][0])) {
|
||||
$text = rtrim($text);
|
||||
}
|
||||
$this->pushToken(Twig_Token::TEXT_TYPE, $text);
|
||||
$this->moveCursor($textContent.$position[0]);
|
||||
|
||||
switch ($this->positions[1][$this->position][0]) {
|
||||
case $this->options['tag_comment'][0]:
|
||||
$this->lexComment();
|
||||
break;
|
||||
|
||||
case $this->options['tag_block'][0]:
|
||||
// raw data?
|
||||
if (preg_match($this->regexes['lex_block_raw'], $this->code, $match, null, $this->cursor)) {
|
||||
$this->moveCursor($match[0]);
|
||||
$this->lexRawData();
|
||||
// {% line \d+ %}
|
||||
} elseif (preg_match($this->regexes['lex_block_line'], $this->code, $match, null, $this->cursor)) {
|
||||
$this->moveCursor($match[0]);
|
||||
$this->lineno = (int) $match[1];
|
||||
} else {
|
||||
$this->pushToken(Twig_Token::BLOCK_START_TYPE);
|
||||
$this->pushState(self::STATE_BLOCK);
|
||||
}
|
||||
break;
|
||||
|
||||
case $this->options['tag_variable'][0]:
|
||||
$this->pushToken(Twig_Token::VAR_START_TYPE);
|
||||
$this->pushState(self::STATE_VAR);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected function lexBlock()
|
||||
{
|
||||
if (empty($this->brackets) && preg_match($this->regexes['lex_block'], $this->code, $match, null, $this->cursor)) {
|
||||
$this->pushToken(Twig_Token::BLOCK_END_TYPE);
|
||||
$this->moveCursor($match[0]);
|
||||
$this->popState();
|
||||
} else {
|
||||
$this->lexExpression();
|
||||
}
|
||||
}
|
||||
|
||||
protected function lexVar()
|
||||
{
|
||||
if (empty($this->brackets) && preg_match($this->regexes['lex_var'], $this->code, $match, null, $this->cursor)) {
|
||||
$this->pushToken(Twig_Token::VAR_END_TYPE);
|
||||
$this->moveCursor($match[0]);
|
||||
$this->popState();
|
||||
} else {
|
||||
$this->lexExpression();
|
||||
}
|
||||
}
|
||||
|
||||
protected function lexExpression()
|
||||
{
|
||||
// whitespace
|
||||
if (preg_match('/\s+/A', $this->code, $match, null, $this->cursor)) {
|
||||
$this->moveCursor($match[0]);
|
||||
|
||||
if ($this->cursor >= $this->end) {
|
||||
throw new Twig_Error_Syntax(sprintf('Unexpected end of file: Unclosed "%s"', $this->state === self::STATE_BLOCK ? 'block' : 'variable'), $this->lineno, $this->filename);
|
||||
}
|
||||
}
|
||||
|
||||
// operators
|
||||
if (preg_match($this->regexes['operator'], $this->code, $match, null, $this->cursor)) {
|
||||
$this->pushToken(Twig_Token::OPERATOR_TYPE, $match[0]);
|
||||
$this->moveCursor($match[0]);
|
||||
}
|
||||
// names
|
||||
elseif (preg_match(self::REGEX_NAME, $this->code, $match, null, $this->cursor)) {
|
||||
$this->pushToken(Twig_Token::NAME_TYPE, $match[0]);
|
||||
$this->moveCursor($match[0]);
|
||||
}
|
||||
// numbers
|
||||
elseif (preg_match(self::REGEX_NUMBER, $this->code, $match, null, $this->cursor)) {
|
||||
$number = (float) $match[0]; // floats
|
||||
if (ctype_digit($match[0]) && $number <= PHP_INT_MAX) {
|
||||
$number = (int) $match[0]; // integers lower than the maximum
|
||||
}
|
||||
$this->pushToken(Twig_Token::NUMBER_TYPE, $number);
|
||||
$this->moveCursor($match[0]);
|
||||
}
|
||||
// punctuation
|
||||
elseif (false !== strpos(self::PUNCTUATION, $this->code[$this->cursor])) {
|
||||
// opening bracket
|
||||
if (false !== strpos('([{', $this->code[$this->cursor])) {
|
||||
$this->brackets[] = array($this->code[$this->cursor], $this->lineno);
|
||||
}
|
||||
// closing bracket
|
||||
elseif (false !== strpos(')]}', $this->code[$this->cursor])) {
|
||||
if (empty($this->brackets)) {
|
||||
throw new Twig_Error_Syntax(sprintf('Unexpected "%s"', $this->code[$this->cursor]), $this->lineno, $this->filename);
|
||||
}
|
||||
|
||||
list($expect, $lineno) = array_pop($this->brackets);
|
||||
if ($this->code[$this->cursor] != strtr($expect, '([{', ')]}')) {
|
||||
throw new Twig_Error_Syntax(sprintf('Unclosed "%s"', $expect), $lineno, $this->filename);
|
||||
}
|
||||
}
|
||||
|
||||
$this->pushToken(Twig_Token::PUNCTUATION_TYPE, $this->code[$this->cursor]);
|
||||
++$this->cursor;
|
||||
}
|
||||
// strings
|
||||
elseif (preg_match(self::REGEX_STRING, $this->code, $match, null, $this->cursor)) {
|
||||
$this->pushToken(Twig_Token::STRING_TYPE, stripcslashes(substr($match[0], 1, -1)));
|
||||
$this->moveCursor($match[0]);
|
||||
}
|
||||
// opening double quoted string
|
||||
elseif (preg_match(self::REGEX_DQ_STRING_DELIM, $this->code, $match, null, $this->cursor)) {
|
||||
$this->brackets[] = array('"', $this->lineno);
|
||||
$this->pushState(self::STATE_STRING);
|
||||
$this->moveCursor($match[0]);
|
||||
}
|
||||
// unlexable
|
||||
else {
|
||||
throw new Twig_Error_Syntax(sprintf('Unexpected character "%s"', $this->code[$this->cursor]), $this->lineno, $this->filename);
|
||||
}
|
||||
}
|
||||
|
||||
protected function lexRawData()
|
||||
{
|
||||
if (!preg_match($this->regexes['lex_raw_data'], $this->code, $match, PREG_OFFSET_CAPTURE, $this->cursor)) {
|
||||
throw new Twig_Error_Syntax(sprintf('Unexpected end of file: Unclosed "block"'), $this->lineno, $this->filename);
|
||||
}
|
||||
|
||||
$text = substr($this->code, $this->cursor, $match[0][1] - $this->cursor);
|
||||
$this->moveCursor($text.$match[0][0]);
|
||||
|
||||
if (false !== strpos($match[1][0], $this->options['whitespace_trim'])) {
|
||||
$text = rtrim($text);
|
||||
}
|
||||
|
||||
$this->pushToken(Twig_Token::TEXT_TYPE, $text);
|
||||
}
|
||||
|
||||
protected function lexComment()
|
||||
{
|
||||
if (!preg_match($this->regexes['lex_comment'], $this->code, $match, PREG_OFFSET_CAPTURE, $this->cursor)) {
|
||||
throw new Twig_Error_Syntax('Unclosed comment', $this->lineno, $this->filename);
|
||||
}
|
||||
|
||||
$this->moveCursor(substr($this->code, $this->cursor, $match[0][1] - $this->cursor).$match[0][0]);
|
||||
}
|
||||
|
||||
protected function lexString()
|
||||
{
|
||||
if (preg_match($this->regexes['interpolation_start'], $this->code, $match, null, $this->cursor)) {
|
||||
$this->brackets[] = array($this->options['interpolation'][0], $this->lineno);
|
||||
$this->pushToken(Twig_Token::INTERPOLATION_START_TYPE);
|
||||
$this->moveCursor($match[0]);
|
||||
$this->pushState(self::STATE_INTERPOLATION);
|
||||
|
||||
} elseif (preg_match(self::REGEX_DQ_STRING_PART, $this->code, $match, null, $this->cursor) && strlen($match[0]) > 0) {
|
||||
$this->pushToken(Twig_Token::STRING_TYPE, stripcslashes($match[0]));
|
||||
$this->moveCursor($match[0]);
|
||||
|
||||
} elseif (preg_match(self::REGEX_DQ_STRING_DELIM, $this->code, $match, null, $this->cursor)) {
|
||||
|
||||
list($expect, $lineno) = array_pop($this->brackets);
|
||||
if ($this->code[$this->cursor] != '"') {
|
||||
throw new Twig_Error_Syntax(sprintf('Unclosed "%s"', $expect), $lineno, $this->filename);
|
||||
}
|
||||
|
||||
$this->popState();
|
||||
++$this->cursor;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
protected function lexInterpolation()
|
||||
{
|
||||
$bracket = end($this->brackets);
|
||||
if ($this->options['interpolation'][0] === $bracket[0] && preg_match($this->regexes['interpolation_end'], $this->code, $match, null, $this->cursor)) {
|
||||
array_pop($this->brackets);
|
||||
$this->pushToken(Twig_Token::INTERPOLATION_END_TYPE);
|
||||
$this->moveCursor($match[0]);
|
||||
$this->popState();
|
||||
} else {
|
||||
$this->lexExpression();
|
||||
}
|
||||
}
|
||||
|
||||
protected function pushToken($type, $value = '')
|
||||
{
|
||||
// do not push empty text tokens
|
||||
if (Twig_Token::TEXT_TYPE === $type && '' === $value) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->tokens[] = new Twig_Token($type, $value, $this->lineno);
|
||||
}
|
||||
|
||||
protected function moveCursor($text)
|
||||
{
|
||||
$this->cursor += strlen($text);
|
||||
$this->lineno += substr_count($text, "\n");
|
||||
}
|
||||
|
||||
protected function getOperatorRegex()
|
||||
{
|
||||
$operators = array_merge(
|
||||
array('='),
|
||||
array_keys($this->env->getUnaryOperators()),
|
||||
array_keys($this->env->getBinaryOperators())
|
||||
);
|
||||
|
||||
$operators = array_combine($operators, array_map('strlen', $operators));
|
||||
arsort($operators);
|
||||
|
||||
$regex = array();
|
||||
foreach ($operators as $operator => $length) {
|
||||
// an operator that ends with a character must be followed by
|
||||
// a whitespace or a parenthesis
|
||||
if (ctype_alpha($operator[$length - 1])) {
|
||||
$regex[] = preg_quote($operator, '/').'(?=[\s()])';
|
||||
} else {
|
||||
$regex[] = preg_quote($operator, '/');
|
||||
}
|
||||
}
|
||||
|
||||
return '/'.implode('|', $regex).'/A';
|
||||
}
|
||||
|
||||
protected function pushState($state)
|
||||
{
|
||||
$this->states[] = $this->state;
|
||||
$this->state = $state;
|
||||
}
|
||||
|
||||
protected function popState()
|
||||
{
|
||||
if (0 === count($this->states)) {
|
||||
throw new Exception('Cannot pop state without a previous state');
|
||||
}
|
||||
|
||||
$this->state = array_pop($this->states);
|
||||
}
|
||||
}
|
29
Core/Frameworks/Flake/Util/Twig/lib/Twig/LexerInterface.php
Normal file
29
Core/Frameworks/Flake/Util/Twig/lib/Twig/LexerInterface.php
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Interface implemented by lexer classes.
|
||||
*
|
||||
* @package twig
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
interface Twig_LexerInterface
|
||||
{
|
||||
/**
|
||||
* Tokenizes a source code.
|
||||
*
|
||||
* @param string $code The source code
|
||||
* @param string $filename A unique identifier for the source code
|
||||
*
|
||||
* @return Twig_TokenStream A token stream instance
|
||||
*/
|
||||
function tokenize($code, $filename = null);
|
||||
}
|
102
Core/Frameworks/Flake/Util/Twig/lib/Twig/Loader/Array.php
Normal file
102
Core/Frameworks/Flake/Util/Twig/lib/Twig/Loader/Array.php
Normal file
|
@ -0,0 +1,102 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Loads a template from an array.
|
||||
*
|
||||
* When using this loader with a cache mechanism, you should know that a new cache
|
||||
* key is generated each time a template content "changes" (the cache key being the
|
||||
* source code of the template). If you don't want to see your cache grows out of
|
||||
* control, you need to take care of clearing the old cache file by yourself.
|
||||
*
|
||||
* @package twig
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Loader_Array implements Twig_LoaderInterface
|
||||
{
|
||||
protected $templates;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $templates An array of templates (keys are the names, and values are the source code)
|
||||
*
|
||||
* @see Twig_Loader
|
||||
*/
|
||||
public function __construct(array $templates)
|
||||
{
|
||||
$this->templates = array();
|
||||
foreach ($templates as $name => $template) {
|
||||
$this->templates[$name] = $template;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds or overrides a template.
|
||||
*
|
||||
* @param string $name The template name
|
||||
* @param string $template The template source
|
||||
*/
|
||||
public function setTemplate($name, $template)
|
||||
{
|
||||
$this->templates[(string) $name] = $template;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the source code of a template, given its name.
|
||||
*
|
||||
* @param string $name The name of the template to load
|
||||
*
|
||||
* @return string The template source code
|
||||
*/
|
||||
public function getSource($name)
|
||||
{
|
||||
$name = (string) $name;
|
||||
if (!isset($this->templates[$name])) {
|
||||
throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name));
|
||||
}
|
||||
|
||||
return $this->templates[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the cache key to use for the cache for a given template name.
|
||||
*
|
||||
* @param string $name The name of the template to load
|
||||
*
|
||||
* @return string The cache key
|
||||
*/
|
||||
public function getCacheKey($name)
|
||||
{
|
||||
$name = (string) $name;
|
||||
if (!isset($this->templates[$name])) {
|
||||
throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name));
|
||||
}
|
||||
|
||||
return $this->templates[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the template is still fresh.
|
||||
*
|
||||
* @param string $name The template name
|
||||
* @param timestamp $time The last modification time of the cached template
|
||||
*/
|
||||
public function isFresh($name, $time)
|
||||
{
|
||||
$name = (string) $name;
|
||||
if (!isset($this->templates[$name])) {
|
||||
throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
100
Core/Frameworks/Flake/Util/Twig/lib/Twig/Loader/Chain.php
Normal file
100
Core/Frameworks/Flake/Util/Twig/lib/Twig/Loader/Chain.php
Normal file
|
@ -0,0 +1,100 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2011 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Loads templates from other loaders.
|
||||
*
|
||||
* @package twig
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Loader_Chain implements Twig_LoaderInterface
|
||||
{
|
||||
protected $loaders;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Twig_LoaderInterface[] $loaders An array of loader instances
|
||||
*/
|
||||
public function __construct(array $loaders = array())
|
||||
{
|
||||
$this->loaders = array();
|
||||
foreach ($loaders as $loader) {
|
||||
$this->addLoader($loader);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a loader instance.
|
||||
*
|
||||
* @param Twig_LoaderInterface $loader A Loader instance
|
||||
*/
|
||||
public function addLoader(Twig_LoaderInterface $loader)
|
||||
{
|
||||
$this->loaders[] = $loader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the source code of a template, given its name.
|
||||
*
|
||||
* @param string $name The name of the template to load
|
||||
*
|
||||
* @return string The template source code
|
||||
*/
|
||||
public function getSource($name)
|
||||
{
|
||||
foreach ($this->loaders as $loader) {
|
||||
try {
|
||||
return $loader->getSource($name);
|
||||
} catch (Twig_Error_Loader $e) {
|
||||
}
|
||||
}
|
||||
|
||||
throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the cache key to use for the cache for a given template name.
|
||||
*
|
||||
* @param string $name The name of the template to load
|
||||
*
|
||||
* @return string The cache key
|
||||
*/
|
||||
public function getCacheKey($name)
|
||||
{
|
||||
foreach ($this->loaders as $loader) {
|
||||
try {
|
||||
return $loader->getCacheKey($name);
|
||||
} catch (Twig_Error_Loader $e) {
|
||||
}
|
||||
}
|
||||
|
||||
throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the template is still fresh.
|
||||
*
|
||||
* @param string $name The template name
|
||||
* @param timestamp $time The last modification time of the cached template
|
||||
*/
|
||||
public function isFresh($name, $time)
|
||||
{
|
||||
foreach ($this->loaders as $loader) {
|
||||
try {
|
||||
return $loader->isFresh($name, $time);
|
||||
} catch (Twig_Error_Loader $e) {
|
||||
}
|
||||
}
|
||||
|
||||
throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name));
|
||||
}
|
||||
}
|
152
Core/Frameworks/Flake/Util/Twig/lib/Twig/Loader/Filesystem.php
Normal file
152
Core/Frameworks/Flake/Util/Twig/lib/Twig/Loader/Filesystem.php
Normal file
|
@ -0,0 +1,152 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Loads template from the filesystem.
|
||||
*
|
||||
* @package twig
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Loader_Filesystem implements Twig_LoaderInterface
|
||||
{
|
||||
protected $paths;
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string|array $paths A path or an array of paths where to look for templates
|
||||
*/
|
||||
public function __construct($paths)
|
||||
{
|
||||
$this->setPaths($paths);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the paths to the templates.
|
||||
*
|
||||
* @return array The array of paths where to look for templates
|
||||
*/
|
||||
public function getPaths()
|
||||
{
|
||||
return $this->paths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the paths where templates are stored.
|
||||
*
|
||||
* @param string|array $paths A path or an array of paths where to look for templates
|
||||
*/
|
||||
public function setPaths($paths)
|
||||
{
|
||||
if (!is_array($paths)) {
|
||||
$paths = array($paths);
|
||||
}
|
||||
|
||||
$this->paths = array();
|
||||
foreach ($paths as $path) {
|
||||
$this->addPath($path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a path where templates are stored.
|
||||
*
|
||||
* @param string $path A path where to look for templates
|
||||
*/
|
||||
public function addPath($path)
|
||||
{
|
||||
// invalidate the cache
|
||||
$this->cache = array();
|
||||
|
||||
if (!is_dir($path)) {
|
||||
throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist.', $path));
|
||||
}
|
||||
|
||||
$this->paths[] = $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the source code of a template, given its name.
|
||||
*
|
||||
* @param string $name The name of the template to load
|
||||
*
|
||||
* @return string The template source code
|
||||
*/
|
||||
public function getSource($name)
|
||||
{
|
||||
return file_get_contents($this->findTemplate($name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the cache key to use for the cache for a given template name.
|
||||
*
|
||||
* @param string $name The name of the template to load
|
||||
*
|
||||
* @return string The cache key
|
||||
*/
|
||||
public function getCacheKey($name)
|
||||
{
|
||||
return $this->findTemplate($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the template is still fresh.
|
||||
*
|
||||
* @param string $name The template name
|
||||
* @param timestamp $time The last modification time of the cached template
|
||||
*/
|
||||
public function isFresh($name, $time)
|
||||
{
|
||||
return filemtime($this->findTemplate($name)) <= $time;
|
||||
}
|
||||
|
||||
protected function findTemplate($name)
|
||||
{
|
||||
// normalize name
|
||||
$name = preg_replace('#/{2,}#', '/', strtr($name, '\\', '/'));
|
||||
|
||||
if (isset($this->cache[$name])) {
|
||||
return $this->cache[$name];
|
||||
}
|
||||
|
||||
$this->validateName($name);
|
||||
|
||||
foreach ($this->paths as $path) {
|
||||
if (is_file($path.'/'.$name)) {
|
||||
return $this->cache[$name] = $path.'/'.$name;
|
||||
}
|
||||
}
|
||||
|
||||
throw new Twig_Error_Loader(sprintf('Unable to find template "%s" (looked into: %s).', $name, implode(', ', $this->paths)));
|
||||
}
|
||||
|
||||
protected function validateName($name)
|
||||
{
|
||||
if (false !== strpos($name, "\0")) {
|
||||
throw new Twig_Error_Loader('A template name cannot contain NUL bytes.');
|
||||
}
|
||||
|
||||
$parts = explode('/', $name);
|
||||
$level = 0;
|
||||
foreach ($parts as $part) {
|
||||
if ('..' === $part) {
|
||||
--$level;
|
||||
} elseif ('.' !== $part) {
|
||||
++$level;
|
||||
}
|
||||
|
||||
if ($level < 0) {
|
||||
throw new Twig_Error_Loader(sprintf('Looks like you try to load a template outside configured directories (%s).', $name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
59
Core/Frameworks/Flake/Util/Twig/lib/Twig/Loader/String.php
Normal file
59
Core/Frameworks/Flake/Util/Twig/lib/Twig/Loader/String.php
Normal file
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Loads a template from a string.
|
||||
*
|
||||
* When using this loader with a cache mechanism, you should know that a new cache
|
||||
* key is generated each time a template content "changes" (the cache key being the
|
||||
* source code of the template). If you don't want to see your cache grows out of
|
||||
* control, you need to take care of clearing the old cache file by yourself.
|
||||
*
|
||||
* @package twig
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Loader_String implements Twig_LoaderInterface
|
||||
{
|
||||
/**
|
||||
* Gets the source code of a template, given its name.
|
||||
*
|
||||
* @param string $name The name of the template to load
|
||||
*
|
||||
* @return string The template source code
|
||||
*/
|
||||
public function getSource($name)
|
||||
{
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the cache key to use for the cache for a given template name.
|
||||
*
|
||||
* @param string $name The name of the template to load
|
||||
*
|
||||
* @return string The cache key
|
||||
*/
|
||||
public function getCacheKey($name)
|
||||
{
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the template is still fresh.
|
||||
*
|
||||
* @param string $name The template name
|
||||
* @param timestamp $time The last modification time of the cached template
|
||||
*/
|
||||
public function isFresh($name, $time)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
53
Core/Frameworks/Flake/Util/Twig/lib/Twig/LoaderInterface.php
Normal file
53
Core/Frameworks/Flake/Util/Twig/lib/Twig/LoaderInterface.php
Normal file
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Interface all loaders must implement.
|
||||
*
|
||||
* @package twig
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
interface Twig_LoaderInterface
|
||||
{
|
||||
/**
|
||||
* Gets the source code of a template, given its name.
|
||||
*
|
||||
* @param string $name The name of the template to load
|
||||
*
|
||||
* @return string The template source code
|
||||
*
|
||||
* @throws Twig_Error_Loader When $name is not found
|
||||
*/
|
||||
function getSource($name);
|
||||
|
||||
/**
|
||||
* Gets the cache key to use for the cache for a given template name.
|
||||
*
|
||||
* @param string $name The name of the template to load
|
||||
*
|
||||
* @return string The cache key
|
||||
*
|
||||
* @throws Twig_Error_Loader When $name is not found
|
||||
*/
|
||||
function getCacheKey($name);
|
||||
|
||||
/**
|
||||
* Returns true if the template is still fresh.
|
||||
*
|
||||
* @param string $name The template name
|
||||
* @param timestamp $time The last modification time of the cached template
|
||||
*
|
||||
* @return Boolean true if the template is fresh, false otherwise
|
||||
*
|
||||
* @throws Twig_Error_Loader When $name is not found
|
||||
*/
|
||||
function isFresh($name, $time);
|
||||
}
|
38
Core/Frameworks/Flake/Util/Twig/lib/Twig/Markup.php
Normal file
38
Core/Frameworks/Flake/Util/Twig/lib/Twig/Markup.php
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Marks a content as safe.
|
||||
*
|
||||
* @package twig
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Markup implements Countable
|
||||
{
|
||||
protected $content;
|
||||
protected $charset;
|
||||
|
||||
public function __construct($content, $charset)
|
||||
{
|
||||
$this->content = (string) $content;
|
||||
$this->charset = $charset;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
public function count()
|
||||
{
|
||||
return function_exists('mb_get_info') ? mb_strlen($this->content, $this->charset) : strlen($this->content);
|
||||
}
|
||||
}
|
227
Core/Frameworks/Flake/Util/Twig/lib/Twig/Node.php
Normal file
227
Core/Frameworks/Flake/Util/Twig/lib/Twig/Node.php
Normal file
|
@ -0,0 +1,227 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a node in the AST.
|
||||
*
|
||||
* @package twig
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Node implements Twig_NodeInterface
|
||||
{
|
||||
protected $nodes;
|
||||
protected $attributes;
|
||||
protected $lineno;
|
||||
protected $tag;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* The nodes are automatically made available as properties ($this->node).
|
||||
* The attributes are automatically made available as array items ($this['name']).
|
||||
*
|
||||
* @param array $nodes An array of named nodes
|
||||
* @param array $attributes An array of attributes (should not be nodes)
|
||||
* @param integer $lineno The line number
|
||||
* @param string $tag The tag name associated with the Node
|
||||
*/
|
||||
public function __construct(array $nodes = array(), array $attributes = array(), $lineno = 0, $tag = null)
|
||||
{
|
||||
$this->nodes = $nodes;
|
||||
$this->attributes = $attributes;
|
||||
$this->lineno = $lineno;
|
||||
$this->tag = $tag;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
$attributes = array();
|
||||
foreach ($this->attributes as $name => $value) {
|
||||
$attributes[] = sprintf('%s: %s', $name, str_replace("\n", '', var_export($value, true)));
|
||||
}
|
||||
|
||||
$repr = array(get_class($this).'('.implode(', ', $attributes));
|
||||
|
||||
if (count($this->nodes)) {
|
||||
foreach ($this->nodes as $name => $node) {
|
||||
$len = strlen($name) + 4;
|
||||
$noderepr = array();
|
||||
foreach (explode("\n", (string) $node) as $line) {
|
||||
$noderepr[] = str_repeat(' ', $len).$line;
|
||||
}
|
||||
|
||||
$repr[] = sprintf(' %s: %s', $name, ltrim(implode("\n", $noderepr)));
|
||||
}
|
||||
|
||||
$repr[] = ')';
|
||||
} else {
|
||||
$repr[0] .= ')';
|
||||
}
|
||||
|
||||
return implode("\n", $repr);
|
||||
}
|
||||
|
||||
public function toXml($asDom = false)
|
||||
{
|
||||
$dom = new DOMDocument('1.0', 'UTF-8');
|
||||
$dom->formatOutput = true;
|
||||
$dom->appendChild($xml = $dom->createElement('twig'));
|
||||
|
||||
$xml->appendChild($node = $dom->createElement('node'));
|
||||
$node->setAttribute('class', get_class($this));
|
||||
|
||||
foreach ($this->attributes as $name => $value) {
|
||||
$node->appendChild($attribute = $dom->createElement('attribute'));
|
||||
$attribute->setAttribute('name', $name);
|
||||
$attribute->appendChild($dom->createTextNode($value));
|
||||
}
|
||||
|
||||
foreach ($this->nodes as $name => $n) {
|
||||
if (null === $n) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$child = $n->toXml(true)->getElementsByTagName('node')->item(0);
|
||||
$child = $dom->importNode($child, true);
|
||||
$child->setAttribute('name', $name);
|
||||
|
||||
$node->appendChild($child);
|
||||
}
|
||||
|
||||
return $asDom ? $dom : $dom->saveXml();
|
||||
}
|
||||
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
foreach ($this->nodes as $node) {
|
||||
$node->compile($compiler);
|
||||
}
|
||||
}
|
||||
|
||||
public function getLine()
|
||||
{
|
||||
return $this->lineno;
|
||||
}
|
||||
|
||||
public function getNodeTag()
|
||||
{
|
||||
return $this->tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the attribute is defined.
|
||||
*
|
||||
* @param string The attribute name
|
||||
*
|
||||
* @return Boolean true if the attribute is defined, false otherwise
|
||||
*/
|
||||
public function hasAttribute($name)
|
||||
{
|
||||
return array_key_exists($name, $this->attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an attribute.
|
||||
*
|
||||
* @param string The attribute name
|
||||
*
|
||||
* @return mixed The attribute value
|
||||
*/
|
||||
public function getAttribute($name)
|
||||
{
|
||||
if (!array_key_exists($name, $this->attributes)) {
|
||||
throw new Twig_Error_Runtime(sprintf('Attribute "%s" does not exist for Node "%s".', $name, get_class($this)));
|
||||
}
|
||||
|
||||
return $this->attributes[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an attribute.
|
||||
*
|
||||
* @param string The attribute name
|
||||
* @param mixed The attribute value
|
||||
*/
|
||||
public function setAttribute($name, $value)
|
||||
{
|
||||
$this->attributes[$name] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an attribute.
|
||||
*
|
||||
* @param string The attribute name
|
||||
*/
|
||||
public function removeAttribute($name)
|
||||
{
|
||||
unset($this->attributes[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the node with the given identifier exists.
|
||||
*
|
||||
* @param string The node name
|
||||
*
|
||||
* @return Boolean true if the node with the given name exists, false otherwise
|
||||
*/
|
||||
public function hasNode($name)
|
||||
{
|
||||
return array_key_exists($name, $this->nodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a node by name.
|
||||
*
|
||||
* @param string The node name
|
||||
*
|
||||
* @return Twig_Node A Twig_Node instance
|
||||
*/
|
||||
public function getNode($name)
|
||||
{
|
||||
if (!array_key_exists($name, $this->nodes)) {
|
||||
throw new Twig_Error_Runtime(sprintf('Node "%s" does not exist for Node "%s".', $name, get_class($this)));
|
||||
}
|
||||
|
||||
return $this->nodes[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a node.
|
||||
*
|
||||
* @param string The node name
|
||||
* @param Twig_Node A Twig_Node instance
|
||||
*/
|
||||
public function setNode($name, $node = null)
|
||||
{
|
||||
$this->nodes[$name] = $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a node by name.
|
||||
*
|
||||
* @param string The node name
|
||||
*/
|
||||
public function removeNode($name)
|
||||
{
|
||||
unset($this->nodes[$name]);
|
||||
}
|
||||
|
||||
public function count()
|
||||
{
|
||||
return count($this->nodes);
|
||||
}
|
||||
|
||||
public function getIterator()
|
||||
{
|
||||
return new ArrayIterator($this->nodes);
|
||||
}
|
||||
}
|
40
Core/Frameworks/Flake/Util/Twig/lib/Twig/Node/AutoEscape.php
Normal file
40
Core/Frameworks/Flake/Util/Twig/lib/Twig/Node/AutoEscape.php
Normal file
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents an autoescape node.
|
||||
*
|
||||
* The value is the escaping strategy (can be html, js, ...)
|
||||
*
|
||||
* The true value is equivalent to html.
|
||||
*
|
||||
* If autoescaping is disabled, then the value is false.
|
||||
*
|
||||
* @package twig
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Node_AutoEscape extends Twig_Node
|
||||
{
|
||||
public function __construct($value, Twig_NodeInterface $body, $lineno, $tag = 'autoescape')
|
||||
{
|
||||
parent::__construct(array('body' => $body), array('value' => $value), $lineno, $tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler->subcompile($this->getNode('body'));
|
||||
}
|
||||
}
|
45
Core/Frameworks/Flake/Util/Twig/lib/Twig/Node/Block.php
Normal file
45
Core/Frameworks/Flake/Util/Twig/lib/Twig/Node/Block.php
Normal file
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a block node.
|
||||
*
|
||||
* @package twig
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Node_Block extends Twig_Node
|
||||
{
|
||||
public function __construct($name, Twig_NodeInterface $body, $lineno, $tag = null)
|
||||
{
|
||||
parent::__construct(array('body' => $body), array('name' => $name), $lineno, $tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->addDebugInfo($this)
|
||||
->write(sprintf("public function block_%s(\$context, array \$blocks = array())\n", $this->getAttribute('name')), "{\n")
|
||||
->indent()
|
||||
;
|
||||
|
||||
$compiler
|
||||
->subcompile($this->getNode('body'))
|
||||
->outdent()
|
||||
->write("}\n\n")
|
||||
;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a block call node.
|
||||
*
|
||||
* @package twig
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Node_BlockReference extends Twig_Node implements Twig_NodeOutputInterface
|
||||
{
|
||||
public function __construct($name, $lineno, $tag = null)
|
||||
{
|
||||
parent::__construct(array(), array('name' => $name), $lineno, $tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->addDebugInfo($this)
|
||||
->write(sprintf("\$this->displayBlock('%s', \$context, \$blocks);\n", $this->getAttribute('name')))
|
||||
;
|
||||
}
|
||||
}
|
20
Core/Frameworks/Flake/Util/Twig/lib/Twig/Node/Body.php
Normal file
20
Core/Frameworks/Flake/Util/Twig/lib/Twig/Node/Body.php
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2011 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a body node.
|
||||
*
|
||||
* @package twig
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Node_Body extends Twig_Node
|
||||
{
|
||||
}
|
39
Core/Frameworks/Flake/Util/Twig/lib/Twig/Node/Do.php
Normal file
39
Core/Frameworks/Flake/Util/Twig/lib/Twig/Node/Do.php
Normal file
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2011 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a do node.
|
||||
*
|
||||
* @package twig
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Node_Do extends Twig_Node
|
||||
{
|
||||
public function __construct(Twig_Node_Expression $expr, $lineno, $tag = null)
|
||||
{
|
||||
parent::__construct(array('expr' => $expr), array(), $lineno, $tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->addDebugInfo($this)
|
||||
->write('')
|
||||
->subcompile($this->getNode('expr'))
|
||||
->raw(";\n")
|
||||
;
|
||||
}
|
||||
}
|
39
Core/Frameworks/Flake/Util/Twig/lib/Twig/Node/Embed.php
Normal file
39
Core/Frameworks/Flake/Util/Twig/lib/Twig/Node/Embed.php
Normal file
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2012 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents an embed node.
|
||||
*
|
||||
* @package twig
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Node_Embed extends Twig_Node_Include
|
||||
{
|
||||
// we don't inject the module to avoid node visitors to traverse it twice (as it will be already visited in the main module)
|
||||
public function __construct($filename, $index, Twig_Node_Expression $variables = null, $only = false, $ignoreMissing = false, $lineno, $tag = null)
|
||||
{
|
||||
parent::__construct(new Twig_Node_Expression_Constant('not_used', $lineno), $variables, $only, $ignoreMissing, $lineno, $tag);
|
||||
|
||||
$this->setAttribute('filename', $filename);
|
||||
$this->setAttribute('index', $index);
|
||||
}
|
||||
|
||||
protected function addGetTemplate(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->write("\$this->env->loadTemplate(")
|
||||
->string($this->getAttribute('filename'))
|
||||
->raw(', ')
|
||||
->string($this->getAttribute('index'))
|
||||
->raw(")")
|
||||
;
|
||||
}
|
||||
}
|
21
Core/Frameworks/Flake/Util/Twig/lib/Twig/Node/Expression.php
Normal file
21
Core/Frameworks/Flake/Util/Twig/lib/Twig/Node/Expression.php
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Abstract class for all nodes that represents an expression.
|
||||
*
|
||||
* @package twig
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
abstract class Twig_Node_Expression extends Twig_Node
|
||||
{
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Array extends Twig_Node_Expression
|
||||
{
|
||||
protected $index;
|
||||
|
||||
public function __construct(array $elements, $lineno)
|
||||
{
|
||||
parent::__construct($elements, array(), $lineno);
|
||||
|
||||
$this->index = -1;
|
||||
foreach ($this->getKeyValuePairs() as $pair) {
|
||||
if ($pair['key'] instanceof Twig_Node_Expression_Constant && ctype_digit((string) $pair['key']->getAttribute('value')) && $pair['key']->getAttribute('value') > $this->index) {
|
||||
$this->index = $pair['key']->getAttribute('value');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getKeyValuePairs()
|
||||
{
|
||||
$pairs = array();
|
||||
|
||||
foreach (array_chunk($this->nodes, 2) as $pair) {
|
||||
$pairs[] = array(
|
||||
'key' => $pair[0],
|
||||
'value' => $pair[1],
|
||||
);
|
||||
}
|
||||
|
||||
return $pairs;
|
||||
}
|
||||
|
||||
public function hasElement(Twig_Node_Expression $key)
|
||||
{
|
||||
foreach ($this->getKeyValuePairs() as $pair) {
|
||||
// we compare the string representation of the keys
|
||||
// to avoid comparing the line numbers which are not relevant here.
|
||||
if ((string) $key == (string) $pair['key']) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function addElement(Twig_Node_Expression $value, Twig_Node_Expression $key = null)
|
||||
{
|
||||
if (null === $key) {
|
||||
$key = new Twig_Node_Expression_Constant(++$this->index, $value->getLine());
|
||||
}
|
||||
|
||||
array_push($this->nodes, $key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler->raw('array(');
|
||||
$first = true;
|
||||
foreach ($this->getKeyValuePairs() as $pair) {
|
||||
if (!$first) {
|
||||
$compiler->raw(', ');
|
||||
}
|
||||
$first = false;
|
||||
|
||||
$compiler
|
||||
->subcompile($pair['key'])
|
||||
->raw(' => ')
|
||||
->subcompile($pair['value'])
|
||||
;
|
||||
}
|
||||
$compiler->raw(')');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
class Twig_Node_Expression_AssignName extends Twig_Node_Expression_Name
|
||||
{
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->raw('$context[')
|
||||
->string($this->getAttribute('name'))
|
||||
->raw(']')
|
||||
;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
abstract class Twig_Node_Expression_Binary extends Twig_Node_Expression
|
||||
{
|
||||
public function __construct(Twig_NodeInterface $left, Twig_NodeInterface $right, $lineno)
|
||||
{
|
||||
parent::__construct(array('left' => $left, 'right' => $right), array(), $lineno);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler
|
||||
->raw('(')
|
||||
->subcompile($this->getNode('left'))
|
||||
->raw(' ')
|
||||
;
|
||||
$this->operator($compiler);
|
||||
$compiler
|
||||
->raw(' ')
|
||||
->subcompile($this->getNode('right'))
|
||||
->raw(')')
|
||||
;
|
||||
}
|
||||
|
||||
abstract public function operator(Twig_Compiler $compiler);
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Binary_Add extends Twig_Node_Expression_Binary
|
||||
{
|
||||
public function operator(Twig_Compiler $compiler)
|
||||
{
|
||||
return $compiler->raw('+');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Binary_And extends Twig_Node_Expression_Binary
|
||||
{
|
||||
public function operator(Twig_Compiler $compiler)
|
||||
{
|
||||
return $compiler->raw('&&');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Binary_BitwiseAnd extends Twig_Node_Expression_Binary
|
||||
{
|
||||
public function operator(Twig_Compiler $compiler)
|
||||
{
|
||||
return $compiler->raw('&');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Binary_BitwiseOr extends Twig_Node_Expression_Binary
|
||||
{
|
||||
public function operator(Twig_Compiler $compiler)
|
||||
{
|
||||
return $compiler->raw('|');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Binary_BitwiseXor extends Twig_Node_Expression_Binary
|
||||
{
|
||||
public function operator(Twig_Compiler $compiler)
|
||||
{
|
||||
return $compiler->raw('^');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Binary_Concat extends Twig_Node_Expression_Binary
|
||||
{
|
||||
public function operator(Twig_Compiler $compiler)
|
||||
{
|
||||
return $compiler->raw('.');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
* (c) 2009 Armin Ronacher
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Binary_Div extends Twig_Node_Expression_Binary
|
||||
{
|
||||
public function operator(Twig_Compiler $compiler)
|
||||
{
|
||||
return $compiler->raw('/');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Binary_Equal extends Twig_Node_Expression_Binary
|
||||
{
|
||||
public function operator(Twig_Compiler $compiler)
|
||||
{
|
||||
return $compiler->raw('==');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2009 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Binary_FloorDiv extends Twig_Node_Expression_Binary
|
||||
{
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$compiler->raw('intval(floor(');
|
||||
parent::compile($compiler);
|
||||
$compiler->raw('))');
|
||||
}
|
||||
|
||||
public function operator(Twig_Compiler $compiler)
|
||||
{
|
||||
return $compiler->raw('/');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) 2010 Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
class Twig_Node_Expression_Binary_Greater extends Twig_Node_Expression_Binary
|
||||
{
|
||||
public function operator(Twig_Compiler $compiler)
|
||||
{
|
||||
return $compiler->raw('>');
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue