diff options
Diffstat (limited to 'vendor')
25 files changed, 2662 insertions, 0 deletions
diff --git a/vendor/.htaccess b/vendor/.htaccess new file mode 100644 index 00000000..14249c50 --- /dev/null +++ b/vendor/.htaccess @@ -0,0 +1 @@ +Deny from all
\ No newline at end of file diff --git a/vendor/Parsedown/LICENSE.txt b/vendor/Parsedown/LICENSE.txt new file mode 100644 index 00000000..baca86f5 --- /dev/null +++ b/vendor/Parsedown/LICENSE.txt @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2013 Emanuil Rusev, erusev.com + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file diff --git a/vendor/Parsedown/Parsedown.php b/vendor/Parsedown/Parsedown.php new file mode 100644 index 00000000..b5014b1a --- /dev/null +++ b/vendor/Parsedown/Parsedown.php @@ -0,0 +1,991 @@ +<?php + +# +# +# Parsedown +# http://parsedown.org +# +# (c) Emanuil Rusev +# http://erusev.com +# +# For the full license information, please view the LICENSE file that was +# distributed with this source code. +# +# + +class Parsedown +{ + # + # Multiton (http://en.wikipedia.org/wiki/Multiton_pattern) + # + + static function instance($name = 'default') + { + if (isset(self::$instances[$name])) + return self::$instances[$name]; + + $instance = new Parsedown(); + + self::$instances[$name] = $instance; + + return $instance; + } + + private static $instances = array(); + + # + # Setters + # + + private $break_marker = " \n"; + + function set_breaks_enabled($breaks_enabled) + { + $this->break_marker = $breaks_enabled ? "\n" : " \n"; + + return $this; + } + + # + # Fields + # + + private $reference_map = array(); + private $escape_sequence_map = array(); + + # + # Public Methods + # + + function parse($text) + { + # removes UTF-8 BOM and marker characters + $text = preg_replace('{^\xEF\xBB\xBF|\x1A}', '', $text); + + # removes \r characters + $text = str_replace("\r\n", "\n", $text); + $text = str_replace("\r", "\n", $text); + + # replaces tabs with spaces + $text = str_replace("\t", ' ', $text); + + # encodes escape sequences + + if (strpos($text, '\\') !== FALSE) + { + $escape_sequences = array('\\\\', '\`', '\*', '\_', '\{', '\}', '\[', '\]', '\(', '\)', '\>', '\#', '\+', '\-', '\.', '\!'); + + foreach ($escape_sequences as $index => $escape_sequence) + { + if (strpos($text, $escape_sequence) !== FALSE) + { + $code = "\x1A".'\\'.$index.';'; + + $text = str_replace($escape_sequence, $code, $text); + + $this->escape_sequence_map[$code] = $escape_sequence; + } + } + } + + # ~ + + $text = preg_replace('/\n\s*\n/', "\n\n", $text); + $text = trim($text, "\n"); + + $lines = explode("\n", $text); + + $text = $this->parse_block_elements($lines); + + # decodes escape sequences + + foreach ($this->escape_sequence_map as $code => $escape_sequence) + { + $text = str_replace($code, $escape_sequence[1], $text); + } + + # ~ + + $text = rtrim($text, "\n"); + + return $text; + } + + # + # Private Methods + # + + private function parse_block_elements(array $lines, $context = '') + { + $elements = array(); + + $element = array( + 'type' => '', + ); + + foreach ($lines as $line) + { + # fenced elements + + switch ($element['type']) + { + case 'fenced_code_block': + + if ( ! isset($element['closed'])) + { + if (preg_match('/^[ ]*'.$element['fence'][0].'{3,}[ ]*$/', $line)) + { + $element['closed'] = true; + } + else + { + $element['text'] !== '' and $element['text'] .= "\n"; + + $element['text'] .= $line; + } + + continue 2; + } + + break; + + case 'markup': + + if ( ! isset($element['closed'])) + { + if (preg_match('{<'.$element['subtype'].'>$}', $line)) # opening tag + { + $element['depth']++; + } + + if (preg_match('{</'.$element['subtype'].'>$}', $line)) # closing tag + { + $element['depth'] > 0 + ? $element['depth']-- + : $element['closed'] = true; + } + + $element['text'] .= "\n".$line; + + continue 2; + } + + break; + } + + # * + + if ($line === '') + { + $element['interrupted'] = true; + + continue; + } + + # composite elements + + switch ($element['type']) + { + case 'blockquote': + + if ( ! isset($element['interrupted'])) + { + $line = preg_replace('/^[ ]*>[ ]?/', '', $line); + + $element['lines'] []= $line; + + continue 2; + } + + break; + + case 'li': + + if (preg_match('/^([ ]{0,3})(\d+[.]|[*+-])[ ](.*)/', $line, $matches)) + { + if ($element['indentation'] !== $matches[1]) + { + $element['lines'] []= $line; + } + else + { + unset($element['last']); + + $elements []= $element; + + $element = array( + 'type' => 'li', + 'indentation' => $matches[1], + 'last' => true, + 'lines' => array( + preg_replace('/^[ ]{0,4}/', '', $matches[3]), + ), + ); + } + + continue 2; + } + + if (isset($element['interrupted'])) + { + if ($line[0] === ' ') + { + $element['lines'] []= ''; + + $line = preg_replace('/^[ ]{0,4}/', '', $line); + + $element['lines'] []= $line; + + unset($element['interrupted']); + + continue 2; + } + } + else + { + $line = preg_replace('/^[ ]{0,4}/', '', $line); + + $element['lines'] []= $line; + + continue 2; + } + + break; + } + + # indentation sensitive types + + $deindented_line = $line; + + switch ($line[0]) + { + case ' ': + + # ~ + + $deindented_line = ltrim($line); + + if ($deindented_line === '') + { + continue 2; + } + + # code block + + if (preg_match('/^[ ]{4}(.*)/', $line, $matches)) + { + if ($element['type'] === 'code_block') + { + if (isset($element['interrupted'])) + { + $element['text'] .= "\n"; + + unset ($element['interrupted']); + } + + $element['text'] .= "\n".$matches[1]; + } + else + { + $elements []= $element; + + $element = array( + 'type' => 'code_block', + 'text' => $matches[1], + ); + } + + continue 2; + } + + break; + + case '#': + + # atx heading (#) + + if (preg_match('/^(#{1,6})[ ]*(.+?)[ ]*#*$/', $line, $matches)) + { + $elements []= $element; + + $level = strlen($matches[1]); + + $element = array( + 'type' => 'h.', + 'text' => $matches[2], + 'level' => $level, + ); + + continue 2; + } + + break; + + case '-': + + # setext heading (---) + + if ($line[0] === '-' and $element['type'] === 'p' and ! isset($element['interrupted']) and preg_match('/^[-]+[ ]*$/', $line)) + { + $element['type'] = 'h.'; + $element['level'] = 2; + + continue 2; + } + + break; + + case '=': + + # setext heading (===) + + if ($line[0] === '=' and $element['type'] === 'p' and ! isset($element['interrupted']) and preg_match('/^[=]+[ ]*$/', $line)) + { + $element['type'] = 'h.'; + $element['level'] = 1; + + continue 2; + } + + break; + } + + # indentation insensitive types + + switch ($deindented_line[0]) + { + case '<': + + # self-closing tag + + if (preg_match('{^<.+?/>$}', $deindented_line)) + { + $elements []= $element; + + $element = array( + 'type' => '', + 'text' => $deindented_line, + ); + + continue 2; + } + + # opening tag + + if (preg_match('{^<(\w+)(?:[ ].*?)?>}', $deindented_line, $matches)) + { + $elements []= $element; + + $element = array( + 'type' => 'markup', + 'subtype' => strtolower($matches[1]), + 'text' => $deindented_line, + 'depth' => 0, + ); + + preg_match('{</'.$matches[1].'>\s*$}', $deindented_line) and $element['closed'] = true; + + continue 2; + } + + break; + + case '>': + + # quote + + if (preg_match('/^>[ ]?(.*)/', $deindented_line, $matches)) + { + $elements []= $element; + + $element = array( + 'type' => 'blockquote', + 'lines' => array( + $matches[1], + ), + ); + + continue 2; + } + + break; + + case '[': + + # reference + + if (preg_match('/^\[(.+?)\]:[ ]*(.+?)(?:[ ]+[\'"](.+?)[\'"])?[ ]*$/', $deindented_line, $matches)) + { + $label = strtolower($matches[1]); + + $this->reference_map[$label] = array( + '»' => trim($matches[2], '<>'), + ); + + if (isset($matches[3])) + { + $this->reference_map[$label]['#'] = $matches[3]; + } + + continue 2; + } + + break; + + case '`': + case '~': + + # fenced code block + + if (preg_match('/^([`]{3,}|[~]{3,})[ ]*(\S+)?[ ]*$/', $deindented_line, $matches)) + { + $elements []= $element; + + $element = array( + 'type' => 'fenced_code_block', + 'text' => '', + 'fence' => $matches[1], + ); + + isset($matches[2]) and $element['language'] = $matches[2]; + + continue 2; + } + + break; + + case '*': + case '+': + case '-': + case '_': + + # hr + + if (preg_match('/^([-*_])([ ]{0,2}\1){2,}[ ]*$/', $deindented_line)) + { + $elements []= $element; + + $element = array( + 'type' => 'hr', + ); + + continue 2; + } + + # li + + if (preg_match('/^([ ]*)[*+-][ ](.*)/', $line, $matches)) + { + $elements []= $element; + + $element = array( + 'type' => 'li', + 'ordered' => false, + 'indentation' => $matches[1], + 'last' => true, + 'lines' => array( + preg_replace('/^[ ]{0,4}/', '', $matches[2]), + ), + ); + + continue 2; + } + } + + # li + + if ($deindented_line[0] <= '9' and $deindented_line >= '0' and preg_match('/^([ ]*)\d+[.][ ](.*)/', $line, $matches)) + { + $elements []= $element; + + $element = array( + 'type' => 'li', + 'ordered' => true, + 'indentation' => $matches[1], + 'last' => true, + 'lines' => array( + preg_replace('/^[ ]{0,4}/', '', $matches[2]), + ), + ); + + continue; + } + + # paragraph + + if ($element['type'] === 'p') + { + if (isset($element['interrupted'])) + { + $elements []= $element; + + $element['text'] = $line; + + unset($element['interrupted']); + } + else + { + $element['text'] .= "\n".$line; + } + } + else + { + $elements []= $element; + + $element = array( + 'type' => 'p', + 'text' => $line, + ); + } + } + + $elements []= $element; + + unset($elements[0]); + + # + # ~ + # + + $markup = ''; + + foreach ($elements as $element) + { + switch ($element['type']) + { + case 'p': + + $text = $this->parse_span_elements($element['text']); + + if ($context === 'li' and $markup === '') + { + if (isset($element['interrupted'])) + { + $markup .= "\n".'<p>'.$text.'</p>'."\n"; + } + else + { + $markup .= $text; + } + } + else + { + $markup .= '<p>'.$text.'</p>'."\n"; + } + + break; + + case 'blockquote': + + $text = $this->parse_block_elements($element['lines']); + + $markup .= '<blockquote>'."\n".$text.'</blockquote>'."\n"; + + break; + + case 'code_block': + case 'fenced_code_block': + + $text = htmlspecialchars($element['text'], ENT_NOQUOTES, 'UTF-8'); + + strpos($text, "\x1A\\") !== FALSE and $text = strtr($text, $this->escape_sequence_map); + + $markup .= isset($element['language']) + ? '<pre><code class="language-'.$element['language'].'">'.$text.'</code></pre>' + : '<pre><code>'.$text.'</code></pre>'; + + $markup .= "\n"; + + break; + + case 'h.': + + $text = $this->parse_span_elements($element['text']); + + $markup .= '<h'.$element['level'].'>'.$text.'</h'.$element['level'].'>'."\n"; + + break; + + case 'hr': + + $markup .= '<hr />'."\n"; + + break; + + case 'li': + + if (isset($element['ordered'])) # first + { + $list_type = $element['ordered'] ? 'ol' : 'ul'; + + $markup .= '<'.$list_type.'>'."\n"; + } + + if (isset($element['interrupted']) and ! isset($element['last'])) + { + $element['lines'] []= ''; + } + + $text = $this->parse_block_elements($element['lines'], 'li'); + + $markup .= '<li>'.$text.'</li>'."\n"; + + isset($element['last']) and $markup .= '</'.$list_type.'>'."\n"; + + break; + + case 'markup': + + $markup .= $this->parse_span_elements($element['text'])."\n"; + + break; + + default: + + $markup .= $element['text']."\n"; + } + } + + return $markup; + } + + # ~ + + private $strong_regex = array( + '*' => '/^[*]{2}([^*]+?)[*]{2}(?![*])/s', + '_' => '/^__([^_]+?)__(?!_)/s', + ); + + private $em_regex = array( + '*' => '/^[*]([^*]+?)[*](?![*])/s', + '_' => '/^_([^_]+?)[_](?![_])\b/s', + ); + + private $strong_em_regex = array( + '*' => '/^[*]{2}(.*?)[*](.+?)[*](.*?)[*]{2}/s', + '_' => '/^__(.*?)_(.+?)_(.*?)__/s', + ); + + private $em_strong_regex = array( + '*' => '/^[*](.*?)[*]{2}(.+?)[*]{2}(.*?)[*]/s', + '_' => '/^_(.*?)__(.+?)__(.*?)_/s', + ); + + private function parse_span_elements($text, $markers = array('![', '&', '*', '<', '[', '_', '`', 'http', '~~')) + { + if (isset($text[2]) === false or $markers === array()) + { + return $text; + } + + # ~ + + $markup = ''; + + while ($markers) + { + $closest_marker = null; + $closest_marker_index = 0; + $closest_marker_position = null; + + foreach ($markers as $index => $marker) + { + $marker_position = strpos($text, $marker); + + if ($marker_position === false) + { + unset($markers[$index]); + + continue; + } + + if ($closest_marker === null or $marker_position < $closest_marker_position) + { + $closest_marker = $marker; + $closest_marker_index = $index; + $closest_marker_position = $marker_position; + } + } + + # ~ + + if ($closest_marker === null or isset($text[$closest_marker_position + 2]) === false) + { + $markup .= $text; + + break; + } + else + { + $markup .= substr($text, 0, $closest_marker_position); + } + + $text = substr($text, $closest_marker_position); + + # ~ + + unset($markers[$closest_marker_index]); + + # ~ + + switch ($closest_marker) + { + case '![': + case '[': + + if (strpos($text, ']') and preg_match('/\[((?:[^][]|(?R))*)\]/', $text, $matches)) + { + $element = array( + '!' => $text[0] === '!', + 'a' => $matches[1], + ); + + $offset = strlen($matches[0]); + + $element['!'] and $offset++; + + $remaining_text = substr($text, $offset); + + if ($remaining_text[0] === '(' and preg_match('/\([ ]*(.*?)(?:[ ]+[\'"](.+?)[\'"])?[ ]*\)/', $remaining_text, $matches)) + { + $element['»'] = $matches[1]; + + if (isset($matches[2])) + { + $element['#'] = $matches[2]; + } + + $offset += strlen($matches[0]); + } + elseif ($this->reference_map) + { + $reference = $element['a']; + + if (preg_match('/^\s*\[(.*?)\]/', $remaining_text, $matches)) + { + $reference = $matches[1] ? $matches[1] : $element['a']; + + $offset += strlen($matches[0]); + } + + $reference = strtolower($reference); + + if (isset($this->reference_map[$reference])) + { + $element['»'] = $this->reference_map[$reference]['»']; + + if (isset($this->reference_map[$reference]['#'])) + { + $element['#'] = $this->reference_map[$reference]['#']; + } + } + else + { + unset($element); + } + } + else + { + unset($element); + } + } + + if (isset($element)) + { + $element['»'] = str_replace('&', '&', $element['»']); + $element['»'] = str_replace('<', '<', $element['»']); + + if ($element['!']) + { + $markup .= '<img alt="'.$element['a'].'" src="'.$element['»'].'" />'; + } + else + { + $element['a'] = $this->parse_span_elements($element['a'], $markers); + + $markup .= isset($element['#']) + ? '<a href="'.$element['»'].'" title="'.$element['#'].'">'.$element['a'].'</a>' + : '<a href="'.$element['»'].'">'.$element['a'].'</a>'; + } + + unset($element); + } + else + { + $markup .= $closest_marker; + + $offset = $closest_marker === '![' ? 2 : 1; + } + + break; + + case '&': + + $markup .= '&'; + + $offset = substr($text, 0, 5) === '&' ? 5 : 1; + + break; + + case '*': + case '_': + + if ($text[1] === $closest_marker and preg_match($this->strong_regex[$closest_marker], $text, $matches)) + { + $matches[1] = $this->parse_span_elements($matches[1], $markers); + + $markup .= '<strong>'.$matches[1].'</strong>'; + } + elseif (preg_match($this->em_regex[$closest_marker], $text, $matches)) + { + $matches[1] = $this->parse_span_elements($matches[1], $markers); + + $markup .= '<em>'.$matches[1].'</em>'; + } + elseif ($text[1] === $closest_marker and preg_match($this->strong_em_regex[$closest_marker], $text, $matches)) + { + $matches[2] = $this->parse_span_elements($matches[2], $markers); + + $matches[1] and $matches[1] = $this->parse_span_elements($matches[1], $markers); + $matches[3] and $matches[3] = $this->parse_span_elements($matches[3], $markers); + + $markup .= '<strong>'.$matches[1].'<em>'.$matches[2].'</em>'.$matches[3].'</strong>'; + } + elseif (preg_match($this->em_strong_regex[$closest_marker], $text, $matches)) + { + $matches[2] = $this->parse_span_elements($matches[2], $markers); + + $matches[1] and $matches[1] = $this->parse_span_elements($matches[1], $markers); + $matches[3] and $matches[3] = $this->parse_span_elements($matches[3], $markers); + + $markup .= '<em>'.$matches[1].'<strong>'.$matches[2].'</strong>'.$matches[3].'</em>'; + } + + if (isset($matches) and $matches) + { + $offset = strlen($matches[0]); + } + else + { + $markup .= $closest_marker; + + $offset = 1; + } + + break; + + case '<': + + if (strpos($text, '>') !== false) + { + if ($text[1] === 'h' and preg_match('/^<(https?:[\/]{2}[^\s]+?)>/i', $text, $matches)) + { + $element_url = $matches[1]; + $element_url = str_replace('&', '&', $element_url); + $element_url = str_replace('<', '<', $element_url); + + $markup .= '<a href="'.$element_url.'">'.$element_url.'</a>'; + + $offset = strlen($matches[0]); + } + elseif (preg_match('/^<\/?\w.*?>/', $text, $matches)) + { + $markup .= $matches[0]; + + $offset = strlen($matches[0]); + } + else + { + $markup .= '<'; + + $offset = 1; + } + } + else + { + $markup .= '<'; + + $offset = 1; + } + + break; + + case '`': + + if (preg_match('/^`(.+?)`/', $text, $matches)) + { + $element_text = $matches[1]; + $element_text = htmlspecialchars($element_text, ENT_NOQUOTES, 'UTF-8'); + + if ($this->escape_sequence_map and strpos($element_text, "\x1A") !== false) + { + $element_text = strtr($element_text, $this->escape_sequence_map); + } + + $markup .= '<code>'.$element_text.'</code>'; + + $offset = strlen($matches[0]); + } + else + { + $markup .= '`'; + + $offset = 1; + } + + break; + + case 'http': + + if (preg_match('/^https?:[\/]{2}[^\s]+\b/i', $text, $matches)) + { + $element_url = $matches[0]; + $element_url = str_replace('&', '&', $element_url); + $element_url = str_replace('<', '<', $element_url); + + $markup .= '<a href="'.$element_url.'">'.$element_url.'</a>'; + + $offset = strlen($matches[0]); + } + else + { + $markup .= 'http'; + + $offset = 4; + } + + break; + + case '~~': + + if (preg_match('/^~~(?=\S)(.+?)(?<=\S)~~/', $text, $matches)) + { + $matches[1] = $this->parse_span_elements($matches[1], $markers); + + $markup .= '<del>'.$matches[1].'</del>'; + + $offset = strlen($matches[0]); + } + else + { + $markup .= '~~'; + + $offset = 2; + } + + break; + } + + if (isset($offset)) + { + $text = substr($text, $offset); + } + + $markers[$closest_marker_index] = $closest_marker; + } + + $markup = str_replace($this->break_marker, '<br />'."\n", $markup); + + return $markup; + } +}
\ No newline at end of file diff --git a/vendor/PicoDb/Database.php b/vendor/PicoDb/Database.php new file mode 100644 index 00000000..c3405f72 --- /dev/null +++ b/vendor/PicoDb/Database.php @@ -0,0 +1,108 @@ +<?php + +namespace PicoDb; + +class Database +{ + private $logs = array(); + private $pdo; + + + public function __construct(array $settings) + { + if (! isset($settings['driver'])) { + + throw new \LogicException('You must define a database driver.'); + } + + switch ($settings['driver']) { + + case 'sqlite': + require_once __DIR__.'/Drivers/Sqlite.php'; + $this->pdo = new Sqlite($settings['filename']); + break; + + default: + throw new \LogicException('This database driver is not supported.'); + } + + $this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); + } + + + public function setLogMessage($message) + { + $this->logs[] = $message; + } + + + public function getLogMessages() + { + return $this->logs; + } + + + public function getConnection() + { + return $this->pdo; + } + + + public function escapeIdentifier($value) + { + return $this->pdo->escapeIdentifier($value); + } + + + public function execute($sql, array $values = array()) + { + try { + + $this->setLogMessage($sql); + $this->setLogMessage(implode(', ', $values)); + + $rq = $this->pdo->prepare($sql); + $rq->execute($values); + + return $rq; + } + catch (\PDOException $e) { + + if ($this->pdo->inTransaction()) $this->pdo->rollback(); + $this->setLogMessage($e->getMessage()); + return false; + } + } + + + public function startTransaction() + { + $this->pdo->beginTransaction(); + } + + + public function closeTransaction() + { + $this->pdo->commit(); + } + + + public function cancelTransaction() + { + $this->pdo->rollback(); + } + + + public function table($table_name) + { + require_once __DIR__.'/Table.php'; + return new Table($this, $table_name); + } + + + public function schema() + { + require_once __DIR__.'/Schema.php'; + return new Schema($this); + } +}
\ No newline at end of file diff --git a/vendor/PicoDb/Drivers/Sqlite.php b/vendor/PicoDb/Drivers/Sqlite.php new file mode 100644 index 00000000..6555e73d --- /dev/null +++ b/vendor/PicoDb/Drivers/Sqlite.php @@ -0,0 +1,48 @@ +<?php + +namespace PicoDb; + +class Sqlite extends \PDO { + + + public function __construct($filename) + { + parent::__construct('sqlite:'.$filename); + + $this->exec('PRAGMA foreign_keys = ON'); + } + + + public function getSchemaVersion() + { + $rq = $this->prepare('PRAGMA user_version'); + $rq->execute(); + $result = $rq->fetch(\PDO::FETCH_ASSOC); + + if (isset($result['user_version'])) { + + return $result['user_version']; + } + + return 0; + } + + + public function setSchemaVersion($version) + { + $this->exec('PRAGMA user_version='.$version); + } + + + public function getLastId() + { + return $this->lastInsertId(); + } + + + public function escapeIdentifier($value) + { + if (strpos($value, '.') !== false) return $value; + return '"'.$value.'"'; + } +}
\ No newline at end of file diff --git a/vendor/PicoDb/Schema.php b/vendor/PicoDb/Schema.php new file mode 100644 index 00000000..2f52b846 --- /dev/null +++ b/vendor/PicoDb/Schema.php @@ -0,0 +1,60 @@ +<?php + +namespace PicoDb; + +class Schema +{ + protected $db = null; + + + public function __construct(Database $db) + { + $this->db = $db; + } + + + public function check($last_version = 1) + { + $current_version = $this->db->getConnection()->getSchemaVersion(); + + if ($current_version < $last_version) { + + return $this->migrateTo($current_version, $last_version); + } + + return true; + } + + + public function migrateTo($current_version, $next_version) + { + try { + + $this->db->startTransaction(); + + for ($i = $current_version + 1; $i <= $next_version; $i++) { + + $function_name = '\Schema\version_'.$i; + + if (function_exists($function_name)) { + + call_user_func($function_name, $this->db->getConnection()); + $this->db->getConnection()->setSchemaVersion($i); + } + else { + + throw new \LogicException('To execute a database migration, you need to create this function: "'.$function_name.'".'); + } + } + + $this->db->closeTransaction(); + } + catch (\PDOException $e) { + + $this->db->cancelTransaction(); + return false; + } + + return true; + } +}
\ No newline at end of file diff --git a/vendor/PicoDb/Table.php b/vendor/PicoDb/Table.php new file mode 100644 index 00000000..4cdf35f7 --- /dev/null +++ b/vendor/PicoDb/Table.php @@ -0,0 +1,430 @@ +<?php + +namespace PicoDb; + +class Table +{ + private $table_name = ''; + private $sql_limit = ''; + private $sql_offset = ''; + private $sql_order = ''; + private $joins = array(); + private $conditions = array(); + private $or_conditions = array(); + private $is_or_condition = false; + private $columns = array(); + private $values = array(); + private $distinct = false; + private $group_by = array(); + + private $db; + + + public function __construct(Database $db, $table_name) + { + $this->db = $db; + $this->table_name = $table_name; + + return $this; + } + + + public function save(array $data) + { + if (! empty($this->conditions)) { + + return $this->update($data); + } + else { + + return $this->insert($data); + } + } + + + public function update(array $data) + { + $columns = array(); + $values = array(); + + foreach ($data as $column => $value) { + + $columns[] = $this->db->escapeIdentifier($column).'=?'; + $values[] = $value; + } + + foreach ($this->values as $value) { + + $values[] = $value; + } + + $sql = sprintf( + 'UPDATE %s SET %s %s', + $this->db->escapeIdentifier($this->table_name), + implode(', ', $columns), + $this->conditions() + ); + + $result = $this->db->execute($sql, $values); + + if ($result !== false && $result->rowCount() > 0) { + + return true; + } + + return false; + } + + + public function insert(array $data) + { + $columns = array(); + + foreach ($data as $column => $value) { + + $columns[] = $this->db->escapeIdentifier($column); + } + + $sql = sprintf( + 'INSERT INTO %s (%s) VALUES (%s)', + $this->db->escapeIdentifier($this->table_name), + implode(', ', $columns), + implode(', ', array_fill(0, count($data), '?')) + ); + + return false !== $this->db->execute($sql, array_values($data)); + } + + + public function remove() + { + $sql = sprintf( + 'DELETE FROM %s %s', + $this->db->escapeIdentifier($this->table_name), + $this->conditions() + ); + + return false !== $this->db->execute($sql, $this->values); + } + + + public function listing($key, $value) + { + $this->columns($key, $value); + + $listing = array(); + $results = $this->findAll(); + + if ($results) { + + foreach ($results as $result) { + + $listing[$result[$key]] = $result[$value]; + } + } + + return $listing; + } + + + public function findAll() + { + $rq = $this->db->execute($this->buildSelectQuery(), $this->values); + if (false === $rq) return false; + + return $rq->fetchAll(\PDO::FETCH_ASSOC); + } + + + 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); + } + + + public function findOne() + { + $this->limit(1); + $result = $this->findAll(); + + return isset($result[0]) ? $result[0] : null; + } + + + 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(); + } + + + public function buildSelectQuery() + { + return sprintf( + 'SELECT %s %s FROM %s %s %s %s %s %s %s', + $this->distinct ? 'DISTINCT' : '', + empty($this->columns) ? '*' : implode(', ', $this->columns), + $this->db->escapeIdentifier($this->table_name), + implode(' ', $this->joins), + $this->conditions(), + empty($this->group_by) ? '' : 'GROUP BY '.implode(', ', $this->group_by), + $this->sql_order, + $this->sql_limit, + $this->sql_offset + ); + } + + + public function count() + { + $sql = sprintf( + 'SELECT COUNT(*) FROM %s'.$this->conditions().$this->sql_order.$this->sql_limit.$this->sql_offset, + $this->db->escapeIdentifier($this->table_name) + ); + + $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) + { + $this->joins[] = sprintf( + 'LEFT JOIN %s ON %s=%s', + $this->db->escapeIdentifier($table), + $this->db->escapeIdentifier($table).'.'.$this->db->escapeIdentifier($foreign_column), + $this->db->escapeIdentifier($this->table_name).'.'.$this->db->escapeIdentifier($local_column) + ); + + return $this; + } + + + public function conditions() + { + if (! empty($this->conditions)) { + + return ' WHERE '.implode(' AND ', $this->conditions); + } + else { + + return ''; + } + } + + + public function addCondition($sql) + { + if ($this->is_or_condition) { + + $this->or_conditions[] = $sql; + } + else { + + $this->conditions[] = $sql; + } + } + + + public function beginOr() + { + $this->is_or_condition = true; + $this->or_conditions = array(); + + return $this; + } + + + public function closeOr() + { + $this->is_or_condition = false; + + if (! empty($this->or_conditions)) { + + $this->conditions[] = '('.implode(' OR ', $this->or_conditions).')'; + } + + return $this; + } + + + public function orderBy($column, $order = 'ASC') + { + $order = strtoupper($order); + $order = $order === 'ASC' || $order === 'DESC' ? $order : 'ASC'; + + if ($this->sql_order === '') { + $this->sql_order = ' ORDER BY '.$this->db->escapeIdentifier($column).' '.$order; + } + else { + $this->sql_order .= ', '.$this->db->escapeIdentifier($column).' '.$order; + } + + return $this; + } + + + public function asc($column) + { + if ($this->sql_order === '') { + $this->sql_order = ' ORDER BY '.$this->db->escapeIdentifier($column).' ASC'; + } + else { + $this->sql_order .= ', '.$this->db->escapeIdentifier($column).' ASC'; + } + + return $this; + } + + + public function desc($column) + { + if ($this->sql_order === '') { + $this->sql_order = ' ORDER BY '.$this->db->escapeIdentifier($column).' DESC'; + } + else { + $this->sql_order .= ', '.$this->db->escapeIdentifier($column).' DESC'; + } + + return $this; + } + + + public function limit($value) + { + if (! is_null($value)) $this->sql_limit = ' LIMIT '.(int) $value; + return $this; + } + + + public function offset($value) + { + if (! is_null($value)) $this->sql_offset = ' OFFSET '.(int) $value; + return $this; + } + + + public function groupBy() + { + $this->group_by = \func_get_args(); + return $this; + } + + + public function columns() + { + $this->columns = \func_get_args(); + return $this; + } + + + public function distinct() + { + $this->columns = \func_get_args(); + $this->distinct = true; + return $this; + } + + + public function __call($name, array $arguments) + { + $column = $arguments[0]; + $sql = ''; + + switch (strtolower($name)) { + + case 'in': + if (isset($arguments[1]) && is_array($arguments[1])) { + + $sql = sprintf( + '%s IN (%s)', + $this->db->escapeIdentifier($column), + implode(', ', array_fill(0, count($arguments[1]), '?')) + ); + } + break; + + case 'notin': + if (isset($arguments[1]) && is_array($arguments[1])) { + + $sql = sprintf( + '%s NOT IN (%s)', + $this->db->escapeIdentifier($column), + implode(', ', array_fill(0, count($arguments[1]), '?')) + ); + } + break; + + case 'like': + $sql = sprintf('%s LIKE ?', $this->db->escapeIdentifier($column)); + break; + + case 'eq': + case 'equal': + case 'equals': + $sql = sprintf('%s = ?', $this->db->escapeIdentifier($column)); + break; + + case 'gt': + case 'greaterthan': + $sql = sprintf('%s > ?', $this->db->escapeIdentifier($column)); + break; + + case 'lt': + case 'lowerthan': + $sql = sprintf('%s < ?', $this->db->escapeIdentifier($column)); + break; + + case 'gte': + case 'greaterthanorequals': + $sql = sprintf('%s >= ?', $this->db->escapeIdentifier($column)); + break; + + case 'lte': + case 'lowerthanorequals': + $sql = sprintf('%s <= ?', $this->db->escapeIdentifier($column)); + break; + + case 'isnull': + $sql = sprintf('%s IS NULL', $this->db->escapeIdentifier($column)); + break; + + case 'notnull': + $sql = sprintf('%s IS NOT NULL', $this->db->escapeIdentifier($column)); + break; + } + + if ($sql !== '') { + + $this->addCondition($sql); + + if (isset($arguments[1])) { + + if (is_array($arguments[1])) { + + foreach ($arguments[1] as $value) { + $this->values[] = $value; + } + } + else { + + $this->values[] = $arguments[1]; + } + } + } + + return $this; + } +} diff --git a/vendor/SimpleValidator/Base.php b/vendor/SimpleValidator/Base.php new file mode 100644 index 00000000..45c01a6e --- /dev/null +++ b/vendor/SimpleValidator/Base.php @@ -0,0 +1,44 @@ +<?php + +/* + * This file is part of Simple Validator. + * + * (c) Frédéric Guillot <contact@fredericguillot.com> + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace SimpleValidator; + +/** + * @author Frédéric Guillot <contact@fredericguillot.com> + */ +abstract class Base +{ + protected $field = ''; + protected $error_message = ''; + protected $data = array(); + + + abstract public function execute(array $data); + + + public function __construct($field, $error_message) + { + $this->field = $field; + $this->error_message = $error_message; + } + + + public function getErrorMessage() + { + return $this->error_message; + } + + + public function getField() + { + return $this->field; + } +}
\ No newline at end of file diff --git a/vendor/SimpleValidator/Validator.php b/vendor/SimpleValidator/Validator.php new file mode 100644 index 00000000..8bb4d620 --- /dev/null +++ b/vendor/SimpleValidator/Validator.php @@ -0,0 +1,67 @@ +<?php + +/* + * This file is part of Simple Validator. + * + * (c) Frédéric Guillot <contact@fredericguillot.com> + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace SimpleValidator; + +/** + * @author Frédéric Guillot <contact@fredericguillot.com> + */ +class Validator +{ + private $data = array(); + private $errors = array(); + private $validators = array(); + + + public function __construct(array $data, array $validators) + { + $this->data = $data; + $this->validators = $validators; + } + + + public function execute() + { + $result = true; + + foreach ($this->validators as $validator) { + + if (! $validator->execute($this->data)) { + + $this->addError( + $validator->getField(), + $validator->getErrorMessage() + ); + + $result = false; + } + } + + return $result; + } + + + public function addError($field, $message) + { + if (! isset($this->errors[$field])) { + + $this->errors[$field] = array(); + } + + $this->errors[$field][] = $message; + } + + + public function getErrors() + { + return $this->errors; + } +}
\ No newline at end of file diff --git a/vendor/SimpleValidator/Validators/Alpha.php b/vendor/SimpleValidator/Validators/Alpha.php new file mode 100644 index 00000000..b00b819b --- /dev/null +++ b/vendor/SimpleValidator/Validators/Alpha.php @@ -0,0 +1,33 @@ +<?php + +/* + * This file is part of Simple Validator. + * + * (c) Frédéric Guillot <contact@fredericguillot.com> + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace SimpleValidator\Validators; + +use SimpleValidator\Base; + +/** + * @author Frédéric Guillot <contact@fredericguillot.com> + */ +class Alpha extends Base +{ + public function execute(array $data) + { + if (isset($data[$this->field]) && $data[$this->field] !== '') { + + if (! ctype_alpha($data[$this->field])) { + + return false; + } + } + + return true; + } +}
\ No newline at end of file diff --git a/vendor/SimpleValidator/Validators/AlphaNumeric.php b/vendor/SimpleValidator/Validators/AlphaNumeric.php new file mode 100644 index 00000000..e1762d67 --- /dev/null +++ b/vendor/SimpleValidator/Validators/AlphaNumeric.php @@ -0,0 +1,33 @@ +<?php + +/* + * This file is part of Simple Validator. + * + * (c) Frédéric Guillot <contact@fredericguillot.com> + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace SimpleValidator\Validators; + +use SimpleValidator\Base; + +/** + * @author Frédéric Guillot <contact@fredericguillot.com> + */ +class AlphaNumeric extends Base +{ + public function execute(array $data) + { + if (isset($data[$this->field]) && $data[$this->field] !== '') { + + if (! ctype_alnum($data[$this->field])) { + + return false; + } + } + + return true; + } +}
\ No newline at end of file diff --git a/vendor/SimpleValidator/Validators/Email.php b/vendor/SimpleValidator/Validators/Email.php new file mode 100644 index 00000000..e4e3d5d6 --- /dev/null +++ b/vendor/SimpleValidator/Validators/Email.php @@ -0,0 +1,81 @@ +<?php + +/* + * This file is part of Simple Validator. + * + * (c) Frédéric Guillot <contact@fredericguillot.com> + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace SimpleValidator\Validators; + +use SimpleValidator\Base; + +/** + * @author Frédéric Guillot <contact@fredericguillot.com> + */ +class Email extends Base +{ + public function execute(array $data) + { + if (isset($data[$this->field]) && $data[$this->field] !== '') { + + // I use the same validation method as Firefox + // http://hg.mozilla.org/mozilla-central/file/cf5da681d577/content/html/content/src/nsHTMLInputElement.cpp#l3967 + + $value = $data[$this->field]; + $length = strlen($value); + + // If the email address begins with a '@' or ends with a '.', + // we know it's invalid. + if ($value[0] === '@' || $value[$length - 1] === '.') { + + return false; + } + + // Check the username + for ($i = 0; $i < $length && $value[$i] !== '@'; ++$i) { + + $c = $value[$i]; + + if (! (ctype_alnum($c) || $c === '.' || $c === '!' || $c === '#' || $c === '$' || + $c === '%' || $c === '&' || $c === '\'' || $c === '*' || $c === '+' || + $c === '-' || $c === '/' || $c === '=' || $c === '?' || $c === '^' || + $c === '_' || $c === '`' || $c === '{' || $c === '|' || $c === '}' || + $c === '~')) { + + return false; + } + } + + // There is no domain name (or it's one-character long), + // that's not a valid email address. + if (++$i >= $length) return false; + if (($i + 1) === $length) return false; + + // The domain name can't begin with a dot. + if ($value[$i] === '.') return false; + + // Parsing the domain name. + for (; $i < $length; ++$i) { + + $c = $value[$i]; + + if ($c === '.') { + + // A dot can't follow a dot. + if ($value[$i - 1] === '.') return false; + } + elseif (! (ctype_alnum($c) || $c === '-')) { + + // The domain characters have to be in this list to be valid. + return false; + } + } + } + + return true; + } +}
\ No newline at end of file diff --git a/vendor/SimpleValidator/Validators/Equals.php b/vendor/SimpleValidator/Validators/Equals.php new file mode 100644 index 00000000..91f34e4b --- /dev/null +++ b/vendor/SimpleValidator/Validators/Equals.php @@ -0,0 +1,43 @@ +<?php + +/* + * This file is part of Simple Validator. + * + * (c) Frédéric Guillot <contact@fredericguillot.com> + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace SimpleValidator\Validators; + +use SimpleValidator\Base; + +/** + * @author Frédéric Guillot <contact@fredericguillot.com> + */ +class Equals extends Base +{ + private $field2; + + + public function __construct($field1, $field2, $error_message) + { + parent::__construct($field1, $error_message); + + $this->field2 = $field2; + } + + + public function execute(array $data) + { + if (isset($data[$this->field]) && $data[$this->field] !== '') { + + if (! isset($data[$this->field2])) return false; + + return $data[$this->field] === $data[$this->field2]; + } + + return true; + } +}
\ No newline at end of file diff --git a/vendor/SimpleValidator/Validators/Integer.php b/vendor/SimpleValidator/Validators/Integer.php new file mode 100644 index 00000000..150558a3 --- /dev/null +++ b/vendor/SimpleValidator/Validators/Integer.php @@ -0,0 +1,42 @@ +<?php + +/* + * This file is part of Simple Validator. + * + * (c) Frédéric Guillot <contact@fredericguillot.com> + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace SimpleValidator\Validators; + +use SimpleValidator\Base; + +/** + * @author Frédéric Guillot <contact@fredericguillot.com> + */ +class Integer extends Base +{ + public function execute(array $data) + { + if (isset($data[$this->field]) && $data[$this->field] !== '') { + + if (is_string($data[$this->field])) { + + if ($data[$this->field][0] === '-') { + + return ctype_digit(substr($data[$this->field], 1)); + } + + return ctype_digit($data[$this->field]); + } + else { + + return is_int($data[$this->field]); + } + } + + return true; + } +}
\ No newline at end of file diff --git a/vendor/SimpleValidator/Validators/Ip.php b/vendor/SimpleValidator/Validators/Ip.php new file mode 100644 index 00000000..48afe569 --- /dev/null +++ b/vendor/SimpleValidator/Validators/Ip.php @@ -0,0 +1,33 @@ +<?php + +/* + * This file is part of Simple Validator. + * + * (c) Frédéric Guillot <contact@fredericguillot.com> + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace SimpleValidator\Validators; + +use SimpleValidator\Base; + +/** + * @author Frédéric Guillot <contact@fredericguillot.com> + */ +class Ip extends Base +{ + public function execute(array $data) + { + if (isset($data[$this->field]) && $data[$this->field] !== '') { + + if (! filter_var($data[$this->field], FILTER_VALIDATE_IP)) { + + return false; + } + } + + return true; + } +}
\ No newline at end of file diff --git a/vendor/SimpleValidator/Validators/Length.php b/vendor/SimpleValidator/Validators/Length.php new file mode 100644 index 00000000..36e50b37 --- /dev/null +++ b/vendor/SimpleValidator/Validators/Length.php @@ -0,0 +1,48 @@ +<?php + +/* + * This file is part of Simple Validator. + * + * (c) Frédéric Guillot <contact@fredericguillot.com> + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace SimpleValidator\Validators; + +use SimpleValidator\Base; + +/** + * @author Frédéric Guillot <contact@fredericguillot.com> + */ +class Length extends Base +{ + private $min; + private $max; + + + public function __construct($field, $error_message, $min, $max) + { + parent::__construct($field, $error_message); + + $this->min = $min; + $this->max = $max; + } + + + public function execute(array $data) + { + if (isset($data[$this->field]) && $data[$this->field] !== '') { + + $length = mb_strlen($data[$this->field], 'UTF-8'); + + if ($length < $this->min || $length > $this->max) { + + return false; + } + } + + return true; + } +}
\ No newline at end of file diff --git a/vendor/SimpleValidator/Validators/MacAddress.php b/vendor/SimpleValidator/Validators/MacAddress.php new file mode 100644 index 00000000..d9348417 --- /dev/null +++ b/vendor/SimpleValidator/Validators/MacAddress.php @@ -0,0 +1,37 @@ +<?php + +/* + * This file is part of Simple Validator. + * + * (c) Frédéric Guillot <contact@fredericguillot.com> + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace SimpleValidator\Validators; + +use SimpleValidator\Base; + +/** + * @author Frédéric Guillot <contact@fredericguillot.com> + */ +class MacAddress extends Base +{ + public function execute(array $data) + { + if (isset($data[$this->field]) && $data[$this->field] !== '') { + + $groups = explode(':', $data[$this->field]); + + if (count($groups) !== 6) return false; + + foreach ($groups as $group) { + + if (! ctype_xdigit($group)) return false; + } + } + + return true; + } +}
\ No newline at end of file diff --git a/vendor/SimpleValidator/Validators/MaxLength.php b/vendor/SimpleValidator/Validators/MaxLength.php new file mode 100644 index 00000000..d8e032b0 --- /dev/null +++ b/vendor/SimpleValidator/Validators/MaxLength.php @@ -0,0 +1,46 @@ +<?php + +/* + * This file is part of Simple Validator. + * + * (c) Frédéric Guillot <contact@fredericguillot.com> + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace SimpleValidator\Validators; + +use SimpleValidator\Base; + +/** + * @author Frédéric Guillot <contact@fredericguillot.com> + */ +class MaxLength extends Base +{ + private $max; + + + public function __construct($field, $error_message, $max) + { + parent::__construct($field, $error_message); + + $this->max = $max; + } + + + public function execute(array $data) + { + if (isset($data[$this->field]) && $data[$this->field] !== '') { + + $length = mb_strlen($data[$this->field], 'UTF-8'); + + if ($length > $this->max) { + + return false; + } + } + + return true; + } +}
\ No newline at end of file diff --git a/vendor/SimpleValidator/Validators/MinLength.php b/vendor/SimpleValidator/Validators/MinLength.php new file mode 100644 index 00000000..4b7f7d24 --- /dev/null +++ b/vendor/SimpleValidator/Validators/MinLength.php @@ -0,0 +1,46 @@ +<?php + +/* + * This file is part of Simple Validator. + * + * (c) Frédéric Guillot <contact@fredericguillot.com> + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace SimpleValidator\Validators; + +use SimpleValidator\Base; + +/** + * @author Frédéric Guillot <contact@fredericguillot.com> + */ +class MinLength extends Base +{ + private $min; + + + public function __construct($field, $error_message, $min) + { + parent::__construct($field, $error_message); + + $this->min = $min; + } + + + public function execute(array $data) + { + if (isset($data[$this->field]) && $data[$this->field] !== '') { + + $length = mb_strlen($data[$this->field], 'UTF-8'); + + if ($length < $this->min) { + + return false; + } + } + + return true; + } +}
\ No newline at end of file diff --git a/vendor/SimpleValidator/Validators/Numeric.php b/vendor/SimpleValidator/Validators/Numeric.php new file mode 100644 index 00000000..a958df1a --- /dev/null +++ b/vendor/SimpleValidator/Validators/Numeric.php @@ -0,0 +1,33 @@ +<?php + +/* + * This file is part of Simple Validator. + * + * (c) Frédéric Guillot <contact@fredericguillot.com> + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace SimpleValidator\Validators; + +use SimpleValidator\Base; + +/** + * @author Frédéric Guillot <contact@fredericguillot.com> + */ +class Numeric extends Base +{ + public function execute(array $data) + { + if (isset($data[$this->field]) && $data[$this->field] !== '') { + + if (! is_numeric($data[$this->field])) { + + return false; + } + } + + return true; + } +}
\ No newline at end of file diff --git a/vendor/SimpleValidator/Validators/Range.php b/vendor/SimpleValidator/Validators/Range.php new file mode 100644 index 00000000..1d71b926 --- /dev/null +++ b/vendor/SimpleValidator/Validators/Range.php @@ -0,0 +1,51 @@ +<?php + +/* + * This file is part of Simple Validator. + * + * (c) Frédéric Guillot <contact@fredericguillot.com> + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace SimpleValidator\Validators; + +use SimpleValidator\Base; + +/** + * @author Frédéric Guillot <contact@fredericguillot.com> + */ +class Range extends Base +{ + private $min; + private $max; + + + public function __construct($field, $error_message, $min, $max) + { + parent::__construct($field, $error_message); + + $this->min = $min; + $this->max = $max; + } + + + public function execute(array $data) + { + if (isset($data[$this->field]) && $data[$this->field] !== '') { + + if (! is_numeric($data[$this->field])) { + + return false; + } + + if ($data[$this->field] < $this->min || $data[$this->field] > $this->max) { + + return false; + } + } + + return true; + } +}
\ No newline at end of file diff --git a/vendor/SimpleValidator/Validators/Required.php b/vendor/SimpleValidator/Validators/Required.php new file mode 100644 index 00000000..e7ef2714 --- /dev/null +++ b/vendor/SimpleValidator/Validators/Required.php @@ -0,0 +1,30 @@ +<?php + +/* + * This file is part of Simple Validator. + * + * (c) Frédéric Guillot <contact@fredericguillot.com> + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace SimpleValidator\Validators; + +use SimpleValidator\Base; + +/** + * @author Frédéric Guillot <contact@fredericguillot.com> + */ +class Required extends Base +{ + public function execute(array $data) + { + if (! isset($data[$this->field]) || $data[$this->field] === '') { + + return false; + } + + return true; + } +}
\ No newline at end of file diff --git a/vendor/SimpleValidator/Validators/Unique.php b/vendor/SimpleValidator/Validators/Unique.php new file mode 100644 index 00000000..c20dbe11 --- /dev/null +++ b/vendor/SimpleValidator/Validators/Unique.php @@ -0,0 +1,78 @@ +<?php + +/* + * This file is part of Simple Validator. + * + * (c) Frédéric Guillot <contact@fredericguillot.com> + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace SimpleValidator\Validators; + +use SimpleValidator\Base; + +/** + * @author Frédéric Guillot <contact@fredericguillot.com> + */ +class Unique extends Base +{ + private $pdo; + private $primary_key; + private $table; + + + public function __construct($field, $error_message, \PDO $pdo, $table, $primary_key = 'id') + { + parent::__construct($field, $error_message); + + $this->pdo = $pdo; + $this->primary_key = $primary_key; + $this->table = $table; + } + + + public function execute(array $data) + { + if (isset($data[$this->field]) && $data[$this->field] !== '') { + + if (! isset($data[$this->primary_key])) { + + $rq = $this->pdo->prepare('SELECT COUNT(*) FROM '.$this->table.' WHERE '.$this->field.'=?'); + + $rq->execute(array( + $data[$this->field] + )); + + $result = $rq->fetch(\PDO::FETCH_NUM); + + if (isset($result[0]) && $result[0] === '1') { + + return false; + } + } + else { + + $rq = $this->pdo->prepare( + 'SELECT COUNT(*) FROM '.$this->table.' + WHERE '.$this->field.'=? AND '.$this->primary_key.' != ?' + ); + + $rq->execute(array( + $data[$this->field], + $data[$this->primary_key] + )); + + $result = $rq->fetch(\PDO::FETCH_NUM); + + if (isset($result[0]) && $result[0] === '1') { + + return false; + } + } + } + + return true; + } +}
\ No newline at end of file diff --git a/vendor/SimpleValidator/Validators/Version.php b/vendor/SimpleValidator/Validators/Version.php new file mode 100644 index 00000000..273a28a5 --- /dev/null +++ b/vendor/SimpleValidator/Validators/Version.php @@ -0,0 +1,32 @@ +<?php + +/* + * This file is part of Simple Validator. + * + * (c) Frédéric Guillot <contact@fredericguillot.com> + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace SimpleValidator\Validators; + +use SimpleValidator\Base; + +/** + * @author Frédéric Guillot <contact@fredericguillot.com> + * @link http://semver.org/ + */ +class Version extends Base +{ + public function execute(array $data) + { + if (isset($data[$this->field]) && $data[$this->field] !== '') { + + $pattern = '/^[0-9]+\.[0-9]+\.[0-9]+([+-][^+-][0-9A-Za-z-.]*)?$/'; + return (bool) preg_match($pattern, $data[$this->field]); + } + + return true; + } +}
\ No newline at end of file diff --git a/vendor/password.php b/vendor/password.php new file mode 100644 index 00000000..c6e84cbd --- /dev/null +++ b/vendor/password.php @@ -0,0 +1,227 @@ +<?php +/** + * A Compatibility library with PHP 5.5's simplified password hashing API. + * + * @author Anthony Ferrara <ircmaxell@php.net> + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @copyright 2012 The Authors + */ + +if (!defined('PASSWORD_BCRYPT')) { + + define('PASSWORD_BCRYPT', 1); + define('PASSWORD_DEFAULT', PASSWORD_BCRYPT); + + if (version_compare(PHP_VERSION, '5.3.7', '<')) { + + define('PASSWORD_PREFIX', '$2a$'); + } + else { + + define('PASSWORD_PREFIX', '$2y$'); + } + + /** + * Hash the password using the specified algorithm + * + * @param string $password The password to hash + * @param int $algo The algorithm to use (Defined by PASSWORD_* constants) + * @param array $options The options for the algorithm to use + * + * @return string|false The hashed password, or false on error. + */ + function password_hash($password, $algo, array $options = array()) { + if (!function_exists('crypt')) { + trigger_error("Crypt must be loaded for password_hash to function", E_USER_WARNING); + return null; + } + if (!is_string($password)) { + trigger_error("password_hash(): Password must be a string", E_USER_WARNING); + return null; + } + if (!is_int($algo)) { + trigger_error("password_hash() expects parameter 2 to be long, " . gettype($algo) . " given", E_USER_WARNING); + return null; + } + switch ($algo) { + case PASSWORD_BCRYPT: + // Note that this is a C constant, but not exposed to PHP, so we don't define it here. + $cost = 10; + if (isset($options['cost'])) { + $cost = $options['cost']; + if ($cost < 4 || $cost > 31) { + trigger_error(sprintf("password_hash(): Invalid bcrypt cost parameter specified: %d", $cost), E_USER_WARNING); + return null; + } + } + $required_salt_len = 22; + $hash_format = sprintf("%s%02d$", PASSWORD_PREFIX, $cost); + break; + default: + trigger_error(sprintf("password_hash(): Unknown password hashing algorithm: %s", $algo), E_USER_WARNING); + return null; + } + if (isset($options['salt'])) { + switch (gettype($options['salt'])) { + case 'NULL': + case 'boolean': + case 'integer': + case 'double': + case 'string': + $salt = (string) $options['salt']; + break; + case 'object': + if (method_exists($options['salt'], '__tostring')) { + $salt = (string) $options['salt']; + break; + } + case 'array': + case 'resource': + default: + trigger_error('password_hash(): Non-string salt parameter supplied', E_USER_WARNING); + return null; + } + if (strlen($salt) < $required_salt_len) { + trigger_error(sprintf("password_hash(): Provided salt is too short: %d expecting %d", strlen($salt), $required_salt_len), E_USER_WARNING); + return null; + } elseif (0 == preg_match('#^[a-zA-Z0-9./]+$#D', $salt)) { + $salt = str_replace('+', '.', base64_encode($salt)); + } + } else { + $buffer = ''; + $raw_length = (int) ($required_salt_len * 3 / 4 + 1); + $buffer_valid = false; + if (function_exists('mcrypt_create_iv') && !defined('PHALANGER')) { + $buffer = mcrypt_create_iv($raw_length, MCRYPT_DEV_URANDOM); + if ($buffer) { + $buffer_valid = true; + } + } + if (!$buffer_valid && function_exists('openssl_random_pseudo_bytes')) { + $buffer = openssl_random_pseudo_bytes($raw_length); + if ($buffer) { + $buffer_valid = true; + } + } + if (!$buffer_valid && is_readable('/dev/urandom')) { + $f = fopen('/dev/urandom', 'r'); + $read = strlen($buffer); + while ($read < $raw_length) { + $buffer .= fread($f, $raw_length - $read); + $read = strlen($buffer); + } + fclose($f); + if ($read >= $raw_length) { + $buffer_valid = true; + } + } + if (!$buffer_valid || strlen($buffer) < $raw_length) { + $bl = strlen($buffer); + for ($i = 0; $i < $raw_length; $i++) { + if ($i < $bl) { + $buffer[$i] = $buffer[$i] ^ chr(mt_rand(0, 255)); + } else { + $buffer .= chr(mt_rand(0, 255)); + } + } + } + $salt = str_replace('+', '.', base64_encode($buffer)); + + } + $salt = substr($salt, 0, $required_salt_len); + + $hash = $hash_format . $salt; + + $ret = crypt($password, $hash); + + if (!is_string($ret) || strlen($ret) <= 13) { + return false; + } + + return $ret; + } + + /** + * Get information about the password hash. Returns an array of the information + * that was used to generate the password hash. + * + * array( + * 'algo' => 1, + * 'algoName' => 'bcrypt', + * 'options' => array( + * 'cost' => 10, + * ), + * ) + * + * @param string $hash The password hash to extract info from + * + * @return array The array of information about the hash. + */ + function password_get_info($hash) { + $return = array( + 'algo' => 0, + 'algoName' => 'unknown', + 'options' => array(), + ); + if (substr($hash, 0, 4) == PASSWORD_PREFIX && strlen($hash) == 60) { + $return['algo'] = PASSWORD_BCRYPT; + $return['algoName'] = 'bcrypt'; + list($cost) = sscanf($hash, PASSWORD_PREFIX."%d$"); + $return['options']['cost'] = $cost; + } + return $return; + } + + /** + * Determine if the password hash needs to be rehashed according to the options provided + * + * If the answer is true, after validating the password using password_verify, rehash it. + * + * @param string $hash The hash to test + * @param int $algo The algorithm used for new password hashes + * @param array $options The options array passed to password_hash + * + * @return boolean True if the password needs to be rehashed. + */ + function password_needs_rehash($hash, $algo, array $options = array()) { + $info = password_get_info($hash); + if ($info['algo'] != $algo) { + return true; + } + switch ($algo) { + case PASSWORD_BCRYPT: + $cost = isset($options['cost']) ? $options['cost'] : 10; + if ($cost != $info['options']['cost']) { + return true; + } + break; + } + return false; + } + + /** + * Verify a password against a hash using a timing attack resistant approach + * + * @param string $password The password to verify + * @param string $hash The hash to verify against + * + * @return boolean If the password matches the hash + */ + function password_verify($password, $hash) { + if (!function_exists('crypt')) { + trigger_error("Crypt must be loaded for password_verify to function", E_USER_WARNING); + return false; + } + $ret = crypt($password, $hash); + if (!is_string($ret) || strlen($ret) != strlen($hash) || strlen($ret) <= 13) { + return false; + } + + $status = 0; + for ($i = 0; $i < strlen($ret); $i++) { + $status |= (ord($ret[$i]) ^ ord($hash[$i])); + } + + return $status === 0; + } +} |