polyfony-inc / polyfony Goto Github PK
View Code? Open in Web Editor NEWPolyfony is an intuitive, light and powerful PHP micro-framework
License: GNU General Public License v3.0
Polyfony is an intuitive, light and powerful PHP micro-framework
License: GNU General Public License v3.0
// internal method to refuse access
private static function refuse($message='Forbidden', $code='403', $logout=false, $redirect=true) {
// remove any existing session cookie
!$logout ?: Store\Cookie::remove(Config::get('security','cookie'));
if($logout) {
// we will redirect to the logout page
!$redirect ?: Response::setRedirect(Config::get('router','exit_route'), 3);
} else {
// we will redirect to the login page
!$redirect ?: Response::setRedirect(Config::get('router','login_route'), 3);
}
// trhow a polyfony exception that by itself will stop the execution with maybe a nice exception handler
Throw new Exception($message,$code);
}
Columns using _date magic will fail to get the proper SQL NULL, they get an empty value '' instead
// close all sessions
Pf\Database::query()
->update('Accounts')
->set(array(
'session_expiration_date' =>null,
'session_key' =>null,
'last_login_origin' =>null,
'last_login_agent' =>null,
'last_login_date' =>null,
'last_failure_origin' =>null,
'last_failure_agent' =>null,
'last_failure_date' =>null,
))
->execute();
last_failure_date, last_login_date, session_expiration_date have empty values, all other have NULL.
SQL !=
// secure a column name
private function secure($column, $full_escape=false) {
// full escape means that even dots will be escaped (usefull for joins parameters)
$regex = $full_escape ? '/[^a-zA-Z0-9_]/' : '/[^a-zA-Z0-9_\.]/';
// apply the regex
$column = preg_replace($regex, '', $column);
// return cleaned column
return($column);
}
// add a condition
public function where($conditions) {
// if provided conditions are an array
if(is_array($conditions)) {
// for each provided strict condition
foreach($conditions as $column => $value) {
// if the column name not numeric
if(!is_numeric($column)) {
// secure the column name
$column = $this->secure($column);
// if the operator is missing
if(!$this->Operator) {
// force AND operator
$this->Operator = 'AND';
}
// save the condition
$this->Conditions[] = "{$this->Operator} ( {$column} = :{$this->secure($column,true)} )";
// save the value
$this->Values[":{$this->secure($column,true)}"] = $value;
}
// column name in a number
else {
// throw an exception
Throw new Exception('giQuery->where() : Column name cannot be a number');
}
}
}
// return self to the next method
return($this);
}
https://github.com/SIB-FRANCE/Polyfony2/blob/master/Private/Vendor/Polyfony/Query.php
Something to call directly Bundle/Controller/Action from JS.
https://github.com/symfony/Filesystem
$filesystem = new Filesystem();
$filesystem->copy($originFile, $targetFile, $override = false);
$filesystem->mkdir($dirs, $mode = 0777);
$filesystem->touch($files, $time = null, $atime = null);
$filesystem->remove($files);
$filesystem->exists($files);
$filesystem->chmod($files, $mode, $umask = 0000, $recursive = false);
$filesystem->chown($files, $user, $recursive = false);
$filesystem->chgrp($files, $group, $recursive = false);
$filesystem->rename($origin, $target);
$filesystem->symlink($originDir, $targetDir, $copyOnWindows = false);
$filesystem->makePathRelative($endPath, $startPath);
$filesystem->mirror($originDir, $targetDir, \Traversable $iterator = null, $options = array());
$filesystem->isAbsolutePath($file);
Use Store\Cookie
but add a hash with private salt to ensure it has not been tampered with
$mail = new Mail($template=null);
$mail
->to
->cc
->bcc
->subject
->set($var,$value)
->send();
function set($var, $value, $escape=false) {
$value = $escape ? Format::htmlSafe($value) : $value;
str_replace("__{$var}__", $value , $template);
}
$newDate = DateTime::createFromFormat("l dS F Y", $dateFromDB);
$newDate = $newDate->format('d/m/Y'); // for example
inspiration from symfony/doctrine and MVC
// ...
public function createAction()
{
$product = new Product();
$product->setName('A Foo Bar');
$product->setPrice('19.99');
$product->setDescription('Lorem ipsum dolor');
$em = $this->getDoctrine()->getManager();
$em->persist($product);
$em->flush();
return new Response('Created product id '.$product->getId());
}
// create a record object
$product = new pfRecord($table);
// alter something
$product->set('description','Marvellous tool !');
// this will insert the record for the first time
$product->save();
// fetch a product from the database by its id
$product = new pfRecord($table,$id);
// alter something
$product->set('description','Marvellous tool !');
// this will update the product currently in the database
$product->save();
in Private/Vendor/Polyfony/Query.php, line 118
This
null
local variable is declared but never used. You should remove it.
list($this->Table) = explode(' ',$table);
}
// in case of DELETE or SELECT
elseif($action == 'DELETE' or $action == 'SELECT') {
// explode after FROM
list($null,$table) = explode('FROM ',$this->Query);
// isolate the table name
list($this->Table) = explode(' ',$table);
}
// clean the table name from any quotes
$this->Table = trim($this->Table,'\'/"`');
Posted from SensioLabsInsight
detect mimetype, force mimetype, auto clean attachment name
in Private/Vendor/Polyfony/Query.php, line 967
This file ends with no newline character. It won't render properly on a terminal, and it's considered a bad practice. Add a simple line feed as the last character to fix it.
}
}
?>
Posted from SensioLabsInsight
https://github.com/SIB-FRANCE/Polyfony2/blob/master/Private/Vendor/Polyfony/Response.php#L321
booleans and simple string cannot work with this piece of code.
either disable the stack merging when using JSON or detect if current content is an array before merging
Storage engines :
// cookie
// session
// database (table/blob)
// filesystem
// memcache
// apc
// request (volatile)
interface StorageInterface
{
/**
* Check whether the variable exists in the store.
*
* @access public
* @param string $variable The name of the variable to check existence of.
* @return boolean If the variable exists or not.
*/
public static function has($variable);
/**
* Store a variable for use.
*
* @access public
* @param string $variable The name of the variable to store.
* @param mixed $value The data we wish to store.
* @param boolean $overwrite Whether we are allowed to overwrite the variable.
* @return boolean If we managed to store the variable.
*/
public static function put($variable, $value, $overwrite);
/**
* Return the variable's value from the store.
*
* @access public
* @param string $variable The name of the variable in the store.
* @return mixed
*/
public static function get($variable);
/**
* Remove the variable in the store.
*
* @access public
* @param string $variable The name of the variable to remove.
* @return boolean If the variable was removed successfully.
*/
public static function remove($variable);
}
Ask : the bundle name, the table name.
Generate (using bootstrap classes) :
../Private/Bundles/Name/
../Private/Bundles/Name/Loader/Route.php
../Private/Bundles/Name/Controller/TableController.php // with sanitisation and notice object
indexAction()
createAction()
editAction()
deleteAction()
updateAction()
../Private/Bundles/Name/Views/Table.php
../Private/Bundles/Name/Views/TableCreate.php
../Private/Bundles/Name/Views/TableEdit.php
if ('cli' !== php_sapi_name())
As an alias of scandir, since DirectoryIterator already does all we want, eg
http://php.net/manual/fr/class.directoryiterator.php
$flags = FilesystemIterator::KEY_AS_PATHNAME | FilesystemIterator::CURRENT_AS_FILEINFO | FilesystemIterator::SKIP_DOTS | FilesystemIterator::UNIX_PATHS;
$d_iterator = new RecursiveDirectoryIterator($folder, $flags);
echo $d_iterator->getPath();
Allow all methods to take either an array or a single set of parameters, ex:
$query->where(array('id'=>'1',is_enabled''=>'1'));
$query->where('id',1);
in Private/Vendor/Polyfony/Response.php, line 61
With booleans, only strict comparison (with
===
operator) should be used to lower bug risks and to improve performances.
// init the response
public static function init() {
// check if we can render a response from the cache
self::isCached() == false ?: self::renderFromCache();
// start the output buffer
ob_start();
// set default assets
self::$_assets = array(
// as empty arrays
Posted from SensioLabsInsight
/**
* Another test function
*
* First parameter must be an array
*/
public function test_array(array $input_array) {
print_r($input_array);
}
Je recode un système de cache SQL ou pas ?
Le précédent qui conservait une trace des modifications dans les tables est un peu lourd mais les interfaces sont toujours présentes dans le code de Query
, donc ça reste faisable.
Sinon plus simplement on peut cacher les requêtes pour un temps donné, sans considération pour les modifications qui apparaissent entre temps (en utilisant Cache
) mais l'intérêt est assez limité et ça pourrait être géré manuellement… J'ai pas trop envie d'alourdir la classe en fait.
If a request is forwarded outside the original bundle where is was mapped, which can only happen with the exception route, the bundle name is not updated in the router, and it is used to find the views path.
find a way to fix it : update the Router::$_match in Dispatch::forward() ?
instead of
if(pf\Request::isPost()) {
foreach(pf\Request::post('Affairs') as $column => $value) {
$this->affair->set($column, $value);
}
}
it could allow us to
if(pf\Request::isPost()) {
$this->affair->set(pf\Request::post('Affairs'));
}
with the set method checking that the column (attributes) do exists before setting them.
in Private/Vendor/PHPMailer/PHPMailer.php, line 1109
Adding "@" before
$mail = popen($sendmail, 'w')
prevents warning and errors during this function execution from being displayed.
If you need to do that, you should probably implement a better way to qualify and recover from errors, using Exceptions.
$sendmail = sprintf('%s -oi -t', escapeshellcmd($this->Sendmail));
}
}
if ($this->SingleTo === true) {
foreach ($this->SingleToArray as $toAddr) {
if (!@$mail = popen($sendmail, 'w')) {
throw new \Polyfony\Exception($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
}
fputs($mail, 'To: ' . $toAddr . "\n");
fputs($mail, $header);
fputs($mail, $body);
Posted from SensioLabsInsight
Allow to set a whole group at once
Config::set()
should be modified for this to work properly.
<button type="button" class="close" data-dismiss="alert">×</button>
in Private/Vendor/Polyfony/Router.php, line 235
Using
include()
orrequire()
bypasses lazy-loading of third-party classes. Prefer using autoloading.
if(!file_exists($script)) {
// new polyfony exception
Throw new Exception("Dispatcher::forward() : Missing controller file [{$script}]",500);
}
// include the controller's file
require_once($script);
// if class is missing from the controller and not in error route
if(!class_exists($class,false)) {
// new polyfony exception
Throw new Exception("Dispatcher::forward() : Missing controller class [{$class}] in [{$script}]",500);
}
Posted from SensioLabsInsight
Don't check for a cached response if the request has a revalidate header
echo $record->get('ultimatum_datetime');
01/02/2015 14:30
capable of parsing and formatting DD/MM/YYYY hh:ii
in Private/Vendor/Polyfony/Router.php, line 221
The parameter
route
, which is an object, should be typehinted.
}
return ($url);
}
public static function forward($route) {
// set full controller
$script = "../Private/Bundles/{$route->bundle}/Controllers/{$route->controller}.php";
// set the full class
$class = "{$route->controller}Controller";
Posted from SensioLabsInsight
.DS_Store
is user-specific and should not appear in a project.gitignore
. Consider adding it to the user global.gitignore
instead.
Caches/*
.DS_Store
*.css
*.js
Posted from SensioLabsInsight
in Private/Vendor/PHPMailer/PHPMailer.php, line 616
Adding "@" before
mail($to, $subject, $body, $header)
prevents warning and errors during this function execution from being displayed.
If you need to do that, you should probably implement a better way to qualify and recover from errors, using Exceptions.
$subject = $this->secureHeader($subject);
} else {
$subject = $this->encodeHeader($this->secureHeader($subject));
}
if (ini_get('safe_mode') || !($this->UseSendmailOptions)) {
$result = @mail($to, $subject, $body, $header);
} else {
$result = @mail($to, $subject, $body, $header, $params);
}
return $result;
}
Posted from SensioLabsInsight
in Private/Vendor/Polyfony/Format.php, line 91
The
or
operator does not have the same precedence as||
.
This could lead to unexpected behavior, use||
instead.
return '';
}
if (empty($phrase)) {
return $text;
}
if (is_array($phrase) or ($phrase instanceof sfOutputEscaperArrayDecorator)) {
foreach ($phrase as $word) {
$pattern[] = '/('.preg_quote($word, '/').')/i';
$replacement[] = $highlighter;
}
}
Posted from SensioLabsInsight
Your project contains files with permissive permissions. In order to avoid opening a security breach, you should restrict execution rights on following files:
- Private/Bundles/Tools/Controllers/Main.php
- Private/Vendor/Polyfony/Bundles.php
- Private/Vendor/Polyfony/Filesystem.php
- Private/Vendor/Polyfony/Keys.php
- Private/Vendor/Polyfony/Response.php
chmod a-x 'Private/Bundles/Tools/Controllers/Main.php' \
'Private/Vendor/Polyfony/Bundles.php' \
'Private/Vendor/Polyfony/Filesystem.php' \
'Private/Vendor/Polyfony/Keys.php' \
'Private/Vendor/Polyfony/Response.php'
Posted from SensioLabsInsight
$camelized = $this->camelize($property);
$reflClass = new \ReflectionClass($object);
$getter = 'get'.$camelized;
$getsetter = lcfirst($camelized); // jQuery style, e.g. read: last(), write: last($item)
$isser = 'is'.$camelized;
$hasser = 'has'.$camelized;
$classHasProperty = $reflClass->hasProperty($property);
if ($reflClass->hasMethod($getter) && $reflClass->getMethod($getter)->isPublic()) {
$result[self::VALUE] = $object->$getter();
} elseif ($this->isMethodAccessible($reflClass, $getsetter, 0)) {
$result[self::VALUE] = $object->$getsetter();
} elseif ($reflClass->hasMethod($isser) && $reflClass->getMethod($isser)->isPublic()) {
$result[self::VALUE] = $object->$isser();
} elseif ($reflClass->hasMethod($hasser) && $reflClass->getMethod($hasser)->isPublic()) {
$result[self::VALUE] = $object->$hasser();
} elseif ($reflClass->hasMethod('__get') && $reflClass->getMethod('__get')->isPublic()) {
$result[self::VALUE] = $object->$property;
} elseif ($classHasProperty && $reflClass->getProperty($property)->isPublic()) {
$result[self::VALUE] = & $object->$property;
$result[self::IS_REF] = true;
} elseif (!$classHasProperty && property_exists($object, $property)) {
// Needed to support \stdClass instances. We need to explicitly
// exclude $classHasProperty, otherwise if in the previous clause
// a *protected* property was found on the class, property_exists()
// returns true, consequently the following line will result in a
// fatal error.
$result[self::VALUE] = & $object->$property;
$result[self::IS_REF] = true;
} elseif ($this->magicCall && $reflClass->hasMethod('__call') && $reflClass->getMethod('__call')->isPublic()) {
// we call the getter and hope the __call do the job
$result[self::VALUE] = $object->$getter();
} else {
$methods = array($getter, $getsetter, $isser, $hasser, '__get');
if ($this->magicCall) {
$methods[] = '__call';
}
https://github.com/symfony/PropertyAccess/blob/master/PropertyAccessor.php#L329
$input = new HTML\Element::input();
$element = new HTML\Element('div')
->setText()
->setHtml()
->setAttribute()
->setClass
->setId
->addEvent()
…
__toString
types: div, span, optgroup…
$this->Notice = $this->Success ?
new Notice\Success('Qualification réussie') :
new Notice\Error('Echec');
// to display the notice elsewhere
Polyfony\Store\Request::put('notice',$this->Notice);
Your project contains files with permissive permissions. In order to avoid opening a security breach, you should restrict execution rights on following files:
- LICENSE.md
- Private/Bundles/Demo/Controllers/.gitignore
- Private/Bundles/Demo/Loader/.gitignore
- Private/Bundles/Demo/Loader/Route.php
- Private/Bundles/Demo/Locales/.gitignore
- Private/Bundles/Demo/Views/.gitignore
- Private/Bundles/Tools/Controllers/.gitignore
- Private/Bundles/Tools/Loader/.gitignore
- Private/Bundles/Tools/Loader/Route.php
- Private/Bundles/Tools/Views/.gitignore
- Private/Config/Config.ini
- Private/Config/Dev.ini
- Private/Config/Prod.ini
- Private/Storage/Cache/.gitignore
- Private/Storage/Data/.gitignore
- Private/Storage/Logs/.gitignore
- Private/Storage/Store/.gitignore
- Private/Vendor/.gitignore
- Private/Vendor/Polyfony/Cache.php
- Private/Vendor/Polyfony/Config.php
- Private/Vendor/Polyfony/Controller.php
- Private/Vendor/Polyfony/Database.php
- Private/Vendor/Polyfony/Exception.php
- Private/Vendor/Polyfony/Form.php
- Private/Vendor/Polyfony/Format.php
- Private/Vendor/Polyfony/Front.php
- Private/Vendor/Polyfony/Loader.php
- Private/Vendor/Polyfony/Locales.php
- Private/Vendor/Polyfony/Notice.php
- Private/Vendor/Polyfony/Notice/Danger.php
- Private/Vendor/Polyfony/Notice/Success.php
- Private/Vendor/Polyfony/Notice/Warning.php
- Private/Vendor/Polyfony/Profiler.php
- Private/Vendor/Polyfony/Query.php
- Private/Vendor/Polyfony/Record.php
- Private/Vendor/Polyfony/Request.php
- Private/Vendor/Polyfony/Response.php
- Private/Vendor/Polyfony/Route.php
- Private/Vendor/Polyfony/Router.php
- Private/Vendor/Polyfony/Runtime.php
- Private/Vendor/Polyfony/Security.php
- Private/Vendor/Polyfony/Store/Apc.php
- Private/Vendor/Polyfony/Store/Cookie.php
- Private/Vendor/Polyfony/Store/Database.php
- Private/Vendor/Polyfony/Store/Filesystem.php
- Private/Vendor/Polyfony/Store/Memcache.php
- Private/Vendor/Polyfony/Store/Request.php
- Private/Vendor/Polyfony/Store/Session.php
- Private/Vendor/Polyfony/Validate.php
- Public/Assets/.gitignore
- Public/index.php
- README.md
chmod a-x 'LICENSE.md' \
'Private/Bundles/Demo/Controllers/.gitignore' \
'Private/Bundles/Demo/Loader/.gitignore' \
'Private/Bundles/Demo/Loader/Route.php' \
'Private/Bundles/Demo/Locales/.gitignore' \
'Private/Bundles/Demo/Views/.gitignore' \
'Private/Bundles/Tools/Controllers/.gitignore' \
'Private/Bundles/Tools/Loader/.gitignore' \
'Private/Bundles/Tools/Loader/Route.php' \
'Private/Bundles/Tools/Views/.gitignore' \
'Private/Config/Config.ini' \
'Private/Config/Dev.ini' \
'Private/Config/Prod.ini' \
'Private/Storage/Cache/.gitignore' \
'Private/Storage/Data/.gitignore' \
'Private/Storage/Logs/.gitignore' \
'Private/Storage/Store/.gitignore' \
'Private/Vendor/.gitignore' \
'Private/Vendor/Polyfony/Cache.php' \
'Private/Vendor/Polyfony/Config.php' \
'Private/Vendor/Polyfony/Controller.php' \
'Private/Vendor/Polyfony/Database.php' \
'Private/Vendor/Polyfony/Exception.php' \
'Private/Vendor/Polyfony/Form.php' \
'Private/Vendor/Polyfony/Format.php' \
'Private/Vendor/Polyfony/Front.php' \
'Private/Vendor/Polyfony/Loader.php' \
'Private/Vendor/Polyfony/Locales.php' \
'Private/Vendor/Polyfony/Notice.php' \
'Private/Vendor/Polyfony/Notice/Danger.php' \
'Private/Vendor/Polyfony/Notice/Success.php' \
'Private/Vendor/Polyfony/Notice/Warning.php' \
'Private/Vendor/Polyfony/Profiler.php' \
'Private/Vendor/Polyfony/Query.php' \
'Private/Vendor/Polyfony/Record.php' \
'Private/Vendor/Polyfony/Request.php' \
'Private/Vendor/Polyfony/Response.php' \
'Private/Vendor/Polyfony/Route.php' \
'Private/Vendor/Polyfony/Router.php' \
'Private/Vendor/Polyfony/Runtime.php' \
'Private/Vendor/Polyfony/Security.php' \
'Private/Vendor/Polyfony/Store/Apc.php' \
'Private/Vendor/Polyfony/Store/Cookie.php' \
'Private/Vendor/Polyfony/Store/Database.php' \
'Private/Vendor/Polyfony/Store/Filesystem.php' \
'Private/Vendor/Polyfony/Store/Memcache.php' \
'Private/Vendor/Polyfony/Store/Request.php' \
'Private/Vendor/Polyfony/Store/Session.php' \
'Private/Vendor/Polyfony/Validate.php' \
'Public/Assets/.gitignore' \
'Public/index.php' \
'README.md'
Posted from SensioLabsInsight
in Private/Vendor/Polyfony/Route.php, line 66
With booleans, only strict comparison (with
!==
operator) should be used to lower bug risks and to improve performances.
}
// set the destination for that route
public function destination($bundle, $controller=null, $action=null) {
$this->bundle = $bundle;
$this->controller = $controller != null ? $controller : 'Index';
$this->action = $action != null ? $action : null;
return $this;
}
}
Posted from SensioLabsInsight
in Private/Vendor/Polyfony/Filesystem.php, line 176
This
user
argument is declared but never used. You should remove it.
// apply the chmod
return(chmod($path, $mask));
}
public static function chown($path, $user, $override_chroot = false) {
// if chroot is enabled, restrict the path to the chroot
$path = self::chroot($path, $override_chroot);
}
Posted from SensioLabsInsight
in Private/Vendor/Polyfony/Response.php, line 400
With booleans, only strict comparison (with
===
operator) should be used to lower bug risks and to improve performances.
header("{$header_key}: {$header_value}");
}
// if the type is file output from the file indicated as content else just output
echo self::getContent();
// if cache is enabled and page is cachable
self::isCachable() == false ?: self::cache();
// it ends here
exit;
}
Posted from SensioLabsInsight
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.