diff --git a/controllers/common.php b/controllers/common.php index d7f7936..6f36f20 100644 --- a/controllers/common.php +++ b/controllers/common.php @@ -81,7 +81,7 @@ Router\get_action('select-db', function() { // Image proxy (avoid SSL mixed content warnings) Router\get_action('proxy', function() { - list($content, $type) = Model\Proxy\download(urldecode(Request\param('url'))); + list($content, $type) = Model\Proxy\download(rawurldecode(Request\param('url'))); if (empty($content)) { Response\text('Not Found', 404); diff --git a/vendor/autoload.php b/vendor/autoload.php index 228365d..8df5790 100644 --- a/vendor/autoload.php +++ b/vendor/autoload.php @@ -4,4 +4,4 @@ require_once __DIR__ . '/composer' . '/autoload_real.php'; -return ComposerAutoloaderInit738d0ffba01de68eecc7cdccd108bcae::getLoader(); +return ComposerAutoloaderInita57f23d5e3b273c0241536094b292083::getLoader(); diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php index 4433649..70d78bc 100644 --- a/vendor/composer/ClassLoader.php +++ b/vendor/composer/ClassLoader.php @@ -56,7 +56,11 @@ class ClassLoader public function getPrefixes() { - return call_user_func_array('array_merge', $this->prefixesPsr0); + if (!empty($this->prefixesPsr0)) { + return call_user_func_array('array_merge', $this->prefixesPsr0); + } + + return array(); } public function getPrefixesPsr4() diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php index aeb7b76..5f01ebc 100644 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInit738d0ffba01de68eecc7cdccd108bcae +class ComposerAutoloaderInita57f23d5e3b273c0241536094b292083 { private static $loader; @@ -19,9 +19,9 @@ class ComposerAutoloaderInit738d0ffba01de68eecc7cdccd108bcae return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInit738d0ffba01de68eecc7cdccd108bcae', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInita57f23d5e3b273c0241536094b292083', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(); - spl_autoload_unregister(array('ComposerAutoloaderInit738d0ffba01de68eecc7cdccd108bcae', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInita57f23d5e3b273c0241536094b292083', 'loadClassLoader')); $map = require __DIR__ . '/autoload_namespaces.php'; foreach ($map as $namespace => $path) { @@ -42,14 +42,14 @@ class ComposerAutoloaderInit738d0ffba01de68eecc7cdccd108bcae $includeFiles = require __DIR__ . '/autoload_files.php'; foreach ($includeFiles as $file) { - composerRequire738d0ffba01de68eecc7cdccd108bcae($file); + composerRequirea57f23d5e3b273c0241536094b292083($file); } return $loader; } } -function composerRequire738d0ffba01de68eecc7cdccd108bcae($file) +function composerRequirea57f23d5e3b273c0241536094b292083($file) { require $file; } diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 941ad5c..ed3b8e6 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -123,18 +123,18 @@ "source": { "type": "git", "url": "https://github.com/fguillot/picoDb.git", - "reference": "8116698f9471f6c3f9b3c1334ee358c9b73d9864" + "reference": "268b3389d2bc3c92ef749a63440d17bd75e2a628" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/fguillot/picoDb/zipball/8116698f9471f6c3f9b3c1334ee358c9b73d9864", - "reference": "8116698f9471f6c3f9b3c1334ee358c9b73d9864", + "url": "https://api.github.com/repos/fguillot/picoDb/zipball/268b3389d2bc3c92ef749a63440d17bd75e2a628", + "reference": "268b3389d2bc3c92ef749a63440d17bd75e2a628", "shasum": "" }, "require": { "php": ">=5.3.0" }, - "time": "2015-01-02 16:42:20", + "time": "2015-01-03 00:32:58", "type": "library", "installation-source": "dist", "autoload": { @@ -162,18 +162,18 @@ "source": { "type": "git", "url": "https://github.com/fguillot/picoFeed.git", - "reference": "3ef98d7b1ea35bd48e0a4e99ea518d0c3165a0c0" + "reference": "627d1d48642ef82f8bb0e70870f36151b3c6936d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/fguillot/picoFeed/zipball/3ef98d7b1ea35bd48e0a4e99ea518d0c3165a0c0", - "reference": "3ef98d7b1ea35bd48e0a4e99ea518d0c3165a0c0", + "url": "https://api.github.com/repos/fguillot/picoFeed/zipball/627d1d48642ef82f8bb0e70870f36151b3c6936d", + "reference": "627d1d48642ef82f8bb0e70870f36151b3c6936d", "shasum": "" }, "require": { "php": ">=5.3.0" }, - "time": "2015-01-02 20:21:50", + "time": "2015-01-06 23:58:29", "type": "library", "installation-source": "dist", "autoload": { diff --git a/vendor/fguillot/picodb/README.md b/vendor/fguillot/picodb/README.md index d637954..6e2d9d5 100644 --- a/vendor/fguillot/picodb/README.md +++ b/vendor/fguillot/picodb/README.md @@ -20,15 +20,16 @@ Requirements - PDO - A database: Sqlite, Mysql or Postgresql -Todo ----- - -- Add support for Distinct and group by - Documentation ------------- -## Connect to your database +### Installation + +```bash +composer require fguillot/picodb dev-master +``` + +### Connect to your database ```php use PicoDb\Database; @@ -48,19 +49,19 @@ Documentation )); ``` -## Execute a SQL request +### Execute a SQL request ```php $db->execute('CREATE TABLE toto (column1 TEXT)'); ``` -## Insert some data +### Insert some data ```php $db->table('toto')->save(['column1' => 'hey']); ``` -## Transations +### Transations ```php $db->transaction(function($db) { @@ -69,7 +70,7 @@ Documentation }); ``` -## Fetch all data +### Fetch all data ```php $records = $db->table('toto')->findAll(); @@ -79,19 +80,19 @@ Documentation } ``` -## Update something +### Update something $db->table('toto')->eq('id', 1)->save(['column1' => 'hey']); You just need to add a condition to perform an update. -## Remove rows +### Remove rows ```php $db->table('toto')->lowerThan('column1', 10)->remove(); ``` -## Sorting +### Sorting ```php $db->table('toto')->asc('column1')->findAll(); @@ -103,20 +104,18 @@ or $db->table('toto')->desc('column1')->findAll(); ``` -## Limit and offset +### Limit and offset ```php $db->table('toto')->limit(10)->offset(5)->findAll(); ``` -## Fetch only some columns +### Fetch only some columns ```php $db->table('toto')->columns('column1', 'column2')->findAll(); ``` -## Conditions - ### Equals condition ```php @@ -248,9 +247,9 @@ How to make a OR condition: ->findAll(); ``` -## Schema migrations +### Schema migrations -### Define a migration +#### Define a migration - Migrations are defined in simple functions inside a namespace named "Schema". - An instance of PDO is passed to first argument of the function. @@ -285,7 +284,7 @@ Example: } ``` -### Run schema update automatically +#### Run schema update automatically - The method "check()" executes all migrations until to reach the correct version number. - If we are already on the last version nothing will happen. diff --git a/vendor/fguillot/picodb/lib/PicoDb/Database.php b/vendor/fguillot/picodb/lib/PicoDb/Database.php index aad9e19..e24e1b0 100644 --- a/vendor/fguillot/picodb/lib/PicoDb/Database.php +++ b/vendor/fguillot/picodb/lib/PicoDb/Database.php @@ -6,6 +6,7 @@ use Closure; use PDO; use PDOException; use LogicException; +use RuntimeException; use Picodb\Driver\Sqlite; use Picodb\Driver\Mysql; use Picodb\Driver\Postgres; @@ -53,6 +54,14 @@ class Database */ public $log_queries = false; + /** + * Number of SQL queries executed + * + * @access public + * @var integer + */ + public $nb_queries = 0; + /** * Constructor, iniatlize a PDO driver * @@ -199,7 +208,7 @@ class Database * @access public * @param string $sql SQL query * @param array $values Values - * @return PDOStatement + * @return PDOStatement|false */ public function execute($sql, array $values = array()) { @@ -220,11 +229,21 @@ class Database $this->setLogMessage('DURATION='.(microtime(true) - $start)); } + $this->nb_queries++; + return $rq; } catch (PDOException $e) { + + $this->cancelTransaction(); + + if (in_array($e->getCode(), $this->pdo->getDuplicateKeyErrorCode())) { + return false; + } + $this->setLogMessage($e->getMessage()); - return false; + + throw new RuntimeException('SQL error'); } } @@ -237,23 +256,9 @@ class Database */ public function transaction(Closure $callback) { - try { - - $this->pdo->beginTransaction(); - $result = $callback($this); - - if ($result === false) { - $this->pdo->rollback(); - } - else { - $this->pdo->commit(); - } - } - catch (PDOException $e) { - $this->pdo->rollback(); - $this->setLogMessage($e->getMessage()); - $result = false; - } + $this->pdo->beginTransaction(); + $result = $callback($this); // Rollback is done in the execute() method + $this->closeTransaction(); return $result === null ? true : $result; } diff --git a/vendor/fguillot/picodb/lib/PicoDb/Driver/Mysql.php b/vendor/fguillot/picodb/lib/PicoDb/Driver/Mysql.php index e775591..27d4cbd 100644 --- a/vendor/fguillot/picodb/lib/PicoDb/Driver/Mysql.php +++ b/vendor/fguillot/picodb/lib/PicoDb/Driver/Mysql.php @@ -81,4 +81,9 @@ class Mysql extends PDO { return 'LIKE'; } + + public function getDuplicateKeyErrorCode() + { + return array(23000); + } } \ No newline at end of file diff --git a/vendor/fguillot/picodb/lib/PicoDb/Driver/Postgres.php b/vendor/fguillot/picodb/lib/PicoDb/Driver/Postgres.php index 5af0948..d9fadbe 100644 --- a/vendor/fguillot/picodb/lib/PicoDb/Driver/Postgres.php +++ b/vendor/fguillot/picodb/lib/PicoDb/Driver/Postgres.php @@ -78,4 +78,9 @@ class Postgres extends PDO { return 'ILIKE'; } + + public function getDuplicateKeyErrorCode() + { + return array(23505, 23503); + } } \ No newline at end of file diff --git a/vendor/fguillot/picodb/lib/PicoDb/Driver/Sqlite.php b/vendor/fguillot/picodb/lib/PicoDb/Driver/Sqlite.php index 17bf081..0943d15 100644 --- a/vendor/fguillot/picodb/lib/PicoDb/Driver/Sqlite.php +++ b/vendor/fguillot/picodb/lib/PicoDb/Driver/Sqlite.php @@ -61,4 +61,9 @@ class Sqlite extends PDO { return 'LIKE'; } + + public function getDuplicateKeyErrorCode() + { + return array(23000); + } } \ No newline at end of file diff --git a/vendor/fguillot/picodb/lib/PicoDb/Table.php b/vendor/fguillot/picodb/lib/PicoDb/Table.php index eed2a1f..0dbc93f 100644 --- a/vendor/fguillot/picodb/lib/PicoDb/Table.php +++ b/vendor/fguillot/picodb/lib/PicoDb/Table.php @@ -2,6 +2,8 @@ namespace PicoDb; +use PDO; + class Table { const SORT_ASC = 'ASC'; @@ -19,27 +21,34 @@ class Table private $values = array(); private $distinct = false; private $group_by = array(); - private $db; - + /** + * Constructor + * + * @access public + * @param \PicoDb\Database $db + * @param string $table_name + */ public function __construct(Database $db, $table_name) { $this->db = $db; $this->table_name = $table_name; - - return $this; } - + /** + * Insert or update + * + * @access public + * @param array $data + * @return boolean + */ public function save(array $data) { if (! empty($this->conditions)) { - return $this->update($data); } else { - return $this->insert($data); } } @@ -47,7 +56,11 @@ class Table /** * Update * - * Note: Do not use `rowCount()` the behaviour is different across drivers + * Note: Do not use `rowCount()` for update the behaviour is different across drivers + * + * @access public + * @param array $data + * @return boolean */ public function update(array $data) { @@ -55,13 +68,11 @@ class Table $values = array(); foreach ($data as $column => $value) { - $columns[] = $this->db->escapeIdentifier($column).'=?'; $values[] = $value; } foreach ($this->values as $value) { - $values[] = $value; } @@ -72,18 +83,21 @@ class Table $this->conditions() ); - $result = $this->db->execute($sql, $values); - - return $result !== false; + return $this->db->execute($sql, $values) !== false; } - + /** + * Insert + * + * @access public + * @param array $data + * @return boolean + */ public function insert(array $data) { $columns = array(); foreach ($data as $column => $value) { - $columns[] = $this->db->escapeIdentifier($column); } @@ -94,10 +108,15 @@ class Table implode(', ', array_fill(0, count($data), '?')) ); - return false !== $this->db->execute($sql, array_values($data)); + return $this->db->execute($sql, array_values($data)) !== false; } - + /** + * Remove + * + * @access public + * @return boolean + */ public function remove() { $sql = sprintf( @@ -107,49 +126,67 @@ class Table ); $result = $this->db->execute($sql, $this->values); - - return $result !== false && $result->rowCount() > 0; + return $result->rowCount() > 0; } - + /** + * Hashmap result [ [column1 => column2], [], ...] + * + * @access public + * @param string $key Column 1 + * @param string $value Column 2 + * @return array + */ public function listing($key, $value) { - $this->columns($key, $value); - $listing = array(); - $results = $this->findAll(); - if ($results) { + $this->columns($key, $value); + $rq = $this->db->execute($this->buildSelectQuery(), $this->values); - foreach ($results as $result) { + $rows = $rq->fetchAll(PDO::FETCH_NUM); - $listing[$result[$key]] = $result[$value]; - } + foreach ($rows as $row) { + $listing[$row[0]] = $row[1]; } return $listing; } - + /** + * Fetch all rows + * + * @access public + * @return array + */ public function findAll() { $rq = $this->db->execute($this->buildSelectQuery(), $this->values); - if (false === $rq) return false; - - return $rq->fetchAll(\PDO::FETCH_ASSOC); + return $rq->fetchAll(PDO::FETCH_ASSOC); } - + /** + * Find all with a single column + * + * @access public + * @param string $column + * @return boolean + */ public function findAllByColumn($column) { $this->columns = array($column); $rq = $this->db->execute($this->buildSelectQuery(), $this->values); - if (false === $rq) return false; - return $rq->fetchAll(\PDO::FETCH_COLUMN, 0); + return $rq->fetchAll(PDO::FETCH_COLUMN, 0); } - + /** + * Fetch one row + * + * @access public + * @param array $data + * @return boolean + */ public function findOne() { $this->limit(1); @@ -158,19 +195,29 @@ class Table return isset($result[0]) ? $result[0] : null; } - + /** + * Fetch one column, first row + * + * @access public + * @param string $column + * @return string + */ public function findOneColumn($column) { $this->limit(1); $this->columns = array($column); $rq = $this->db->execute($this->buildSelectQuery(), $this->values); - if (false === $rq) return false; return $rq->fetchColumn(); } - + /** + * Build a select query + * + * @access public + * @return string + */ public function buildSelectQuery() { foreach ($this->columns as $key => $value) { @@ -191,7 +238,12 @@ class Table ); } - + /** + * Count + * + * @access public + * @return integer + */ public function count() { $sql = sprintf( @@ -200,14 +252,22 @@ class Table ); $rq = $this->db->execute($sql, $this->values); - if (false === $rq) return false; $result = $rq->fetchColumn(); return $result ? (int) $result : 0; } - - public function join($table, $foreign_column, $local_column, $local_table = null) + /** + * Left join + * + * @access public + * @param string $table Join table + * @param string $foreign_column Foreign key on the join table + * @param string $local_column Local column + * @param string $local_table Local table + * @return \PicoDb\Table + */ + public function join($table, $foreign_column, $local_column, $local_table = '') { $this->joins[] = sprintf( 'LEFT JOIN %s ON %s=%s', @@ -219,55 +279,71 @@ class Table return $this; } - + /** + * Build conditions + * + * @access public + * @return string + */ public function conditions() { - if (! empty($this->conditions)) { - - return ' WHERE '.implode(' AND ', $this->conditions); - } - else { - - return ''; - } + return empty($this->conditions) ? '' : ' WHERE '.implode(' AND ', $this->conditions); } - + /** + * Add new condition + * + * @access public + * @param string $sql + */ public function addCondition($sql) { if ($this->is_or_condition) { - $this->or_conditions[] = $sql; } else { - $this->conditions[] = $sql; } } - + /** + * Start OR condition + * + * @access public + * @return \PicoDb\Table + */ public function beginOr() { $this->is_or_condition = true; $this->or_conditions = array(); - return $this; } - + /** + * Close OR condition + * + * @access public + * @return \PicoDb\Table + */ public function closeOr() { $this->is_or_condition = false; if (! empty($this->or_conditions)) { - $this->conditions[] = '('.implode(' OR ', $this->or_conditions).')'; } return $this; } - + /** + * Order by + * + * @access public + * @param string $column Column name + * @param string $order Direction ASC or DESC + * @return \PicoDb\Table + */ public function orderBy($column, $order = self::SORT_ASC) { $order = strtoupper($order); @@ -283,7 +359,13 @@ class Table return $this; } - + /** + * Ascending sort + * + * @access public + * @param string $column + * @return \PicoDb\Table + */ public function asc($column) { if ($this->sql_order === '') { @@ -296,7 +378,13 @@ class Table return $this; } - + /** + * Descending sort + * + * @access public + * @param string $column + * @return \PicoDb\Table + */ public function desc($column) { if ($this->sql_order === '') { @@ -309,43 +397,83 @@ class Table return $this; } - + /** + * Limit + * + * @access public + * @param integer $value + * @return \PicoDb\Table + */ public function limit($value) { - if (! is_null($value)) $this->sql_limit = ' LIMIT '.(int) $value; + if (! is_null($value)) { + $this->sql_limit = ' LIMIT '.(int) $value; + } + return $this; } - + /** + * Offset + * + * @access public + * @param integer $value + * @return \PicoDb\Table + */ public function offset($value) { - if (! is_null($value)) $this->sql_offset = ' OFFSET '.(int) $value; + if (! is_null($value)) { + $this->sql_offset = ' OFFSET '.(int) $value; + } + return $this; } - + /** + * Group by + * + * @access public + * @return \PicoDb\Table + */ public function groupBy() { - $this->group_by = \func_get_args(); + $this->group_by = func_get_args(); return $this; } - + /** + * Define the columns for the select + * + * @access public + * @return \PicoDb\Table + */ public function columns() { - $this->columns = \func_get_args(); + $this->columns = func_get_args(); return $this; } - + /** + * Distinct + * + * @access public + * @return \PicoDb\Table + */ public function distinct() { - $this->columns = \func_get_args(); + $this->columns = func_get_args(); $this->distinct = true; return $this; } - + /** + * Magic method for sql conditions + * + * @access public + * @param string $name + * @param array $arguments + * @return \PicoDb\Table + */ public function __call($name, array $arguments) { $column = $arguments[0]; diff --git a/vendor/fguillot/picofeed/docs/image-proxy.markdown b/vendor/fguillot/picofeed/docs/image-proxy.markdown index 74e10d0..2c3dafd 100644 --- a/vendor/fguillot/picofeed/docs/image-proxy.markdown +++ b/vendor/fguillot/picofeed/docs/image-proxy.markdown @@ -30,7 +30,8 @@ There two different ways to use this feature, define a proxy url or a callback. ### Define a proxy url A proxy url must be defined with a placeholder `%s`. -The placeholder will be replaced by the image source urlencoded. +The placeholder will be replaced by the image source url encoded (RFC 3986). +In PHP, the url can be decoded with the function `rawurldecode()`. ```php $config = new Config; @@ -55,7 +56,7 @@ $config = new Config; $config->setFilterImageProxyCallback(function ($image_url) { $key = hash_hmac('sha1', $image_url, 'secret'); - return 'https://mypublicproxy/'.$key.'/'.urlencode($image_url); + return 'https://mypublicproxy/'.$key.'/'.rawurlencode($image_url); }); ``` diff --git a/vendor/fguillot/picofeed/lib/PicoFeed/Filter/Attribute.php b/vendor/fguillot/picofeed/lib/PicoFeed/Filter/Attribute.php index 5948dec..b1c4906 100644 --- a/vendor/fguillot/picofeed/lib/PicoFeed/Filter/Attribute.php +++ b/vendor/fguillot/picofeed/lib/PicoFeed/Filter/Attribute.php @@ -389,7 +389,7 @@ class Attribute if ($tag === 'img' && $attribute === 'src') { if ($this->image_proxy_url) { - $value = sprintf($this->image_proxy_url, urlencode($value)); + $value = sprintf($this->image_proxy_url, rawurlencode($value)); } else if (is_callable($this->image_proxy_callback)) { $value = call_user_func($this->image_proxy_callback, $value); diff --git a/vendor/fguillot/picofeed/tests/Filter/AttributeFilterTest.php b/vendor/fguillot/picofeed/tests/Filter/AttributeFilterTest.php index b0de530..907aaa2 100644 --- a/vendor/fguillot/picofeed/tests/Filter/AttributeFilterTest.php +++ b/vendor/fguillot/picofeed/tests/Filter/AttributeFilterTest.php @@ -64,18 +64,18 @@ class AttributeFilterTest extends PHPUnit_Framework_TestCase $filter->setImageProxyUrl('https://myproxy/?u=%s'); $url = 'http://example.net/image.png'; $this->assertTrue($filter->rewriteImageProxyUrl('img', 'src', $url)); - $this->assertEquals('https://myproxy/?u='.urlencode('http://example.net/image.png'), $url); + $this->assertEquals('https://myproxy/?u='.rawurlencode('http://example.net/image.png'), $url); $filter = new Attribute(new Url('http://www.la-grange.net')); $filter->setImageProxyCallback(function ($image_url) { $key = hash_hmac('sha1', $image_url, 'secret'); - return 'https://mypublicproxy/'.$key.'/'.urlencode($image_url); + return 'https://mypublicproxy/'.$key.'/'.rawurlencode($image_url); }); $url = 'http://example.net/image.png'; $this->assertTrue($filter->rewriteImageProxyUrl('img', 'src', $url)); - $this->assertEquals('https://mypublicproxy/d9701029b054f6e178ef88fcd3c789365e52a26d/'.urlencode('http://example.net/image.png'), $url); + $this->assertEquals('https://mypublicproxy/d9701029b054f6e178ef88fcd3c789365e52a26d/'.rawurlencode('http://example.net/image.png'), $url); } public function testRewriteAbsoluteUrl()