示例#1
0
 /**
  * Render an error page.
  */
 public function render()
 {
     $error = $this->getError();
     $messageBox = new Template('sledgehammer/mvc/templates/httperror.php', $error);
     $messageBox->render();
     foreach ($this->options as $option => $value) {
         switch ((string) $option) {
             case 'notice':
             case 'warning':
                 $function = $option;
                 if (is_array($value)) {
                     call_user_func_array($function, $value);
                 } else {
                     call_user_func($function, $value);
                 }
                 break;
             case 'exception':
                 \Sledgehammer\report_exception($value);
                 break;
             default:
                 \Sledgehammer\notice('Unknown option: "' . $option . '"', array('value' => $value));
                 break;
         }
     }
 }
示例#2
0
 /**
  * Constructor.
  *
  * @param object/iterator/array $data
  * @param array                 $options
  */
 public function __construct($data, $options = [])
 {
     $this->_data = $data;
     foreach ($options as $name => $value) {
         $property = '_' . $name;
         if (property_exists($this, $property)) {
             $this->{$property} = $value;
         } else {
             \Sledgehammer\notice('Invalid option: "' . $name . '"');
         }
     }
 }
示例#3
0
 /**
  * Constructor.
  *
  * @param array $options Hiermee kun je de "table" en "dbLink" overschrijven
  */
 public function __construct($options = [])
 {
     $availableOptions = array('table', 'dbLink');
     foreach ($options as $property => $value) {
         if (in_array($property, $availableOptions)) {
             $this->{$property} = $value;
         } else {
             \Sledgehammer\notice('Invalid option "' . $property . '"', 'Use: ' . \Sledgehammer\human_implode(' or ', $availableOptions));
         }
     }
     if ($this->table === null) {
         $this->table = session_name();
     }
 }
示例#4
0
 /**
  * Trigger an event.
  *
  * @param string   $event
  * @param stdClass $sender
  * @param mixed    $args   (optional)
  */
 public function trigger($event, $sender, $args = null)
 {
     if (isset($this->events[$event])) {
         $method = 'on' . ucfirst($event);
         $arguments = func_get_args();
         array_shift($arguments);
         if (method_exists($this, $method)) {
             call_user_func_array(array($this, $method), $arguments);
         }
         foreach ($this->events[$event] as $callback) {
             call_user_func_array($callback, $arguments);
         }
     } else {
         \Sledgehammer\notice('Event: "' . $event . '" not registered', 'Available events: ' . \Sledgehammer\quoted_human_implode(', ', array_keys($this->events)));
     }
 }
示例#5
0
 /**
  * Generate a HTML element.
  *
  * @param string            $name       Name of the element. Example "div", "img", "script", etc
  * @param array             $attributes array('type'=> 'checkbox', 'checked' => true, 'disabled')
  * @param bool|string|array $contents   true: Only generate the opentag, string html, array with sub elements
  *
  * @return Html
  */
 public static function element($name, $attributes, $contents = '')
 {
     $name = strtolower($name);
     $element = new self('<' . $name);
     foreach ($attributes as $key => $value) {
         if (is_int($key)) {
             if (preg_match('/^[a-z\\-_:]+$/i', $value)) {
                 $element->html .= ' ' . strtolower($value);
             } else {
                 \Sledgehammer\notice('Invalid attribute: ' . $key, $value);
             }
         } elseif (is_bool($value)) {
             if ($value) {
                 $element->html .= ' ' . strtolower($key);
             }
         } else {
             $element->html .= ' ' . strtolower($key) . '="' . self::escape($value) . '"';
         }
     }
     if ($contents === true) {
         // Only generate the open tag?
         $element->html .= '>';
         return $element;
     }
     if ($contents === '') {
         // Close the tag?
         if (in_array($name, array('area', 'base', 'br', 'hr', 'input', 'img', 'link', 'meta'))) {
             $element->html .= ' />';
         } else {
             $element->html .= '></' . $name . '>';
         }
         return $element;
     }
     $element->html .= '>';
     if (is_array($contents)) {
         foreach ($contents as $sub_element) {
             $element->html .= $sub_element;
         }
     } else {
         $element->html .= $contents;
     }
     $element->html .= '</' . $name . '>';
     return $element;
 }
示例#6
0
 /**
  * Constructor.
  *
  * @param string|array $label_or_options
  * @param array        $options
  */
 public function __construct($label_or_options, $options = array())
 {
     if (is_array($label_or_options) === false) {
         $options['label'] = $label_or_options;
     } else {
         if (count($options) !== 0) {
             \Sledgehammer\notice('Second parameter $options is ignored');
         }
         $options = $label_or_options;
     }
     // Set attributes and properties
     foreach ($options as $option => $value) {
         if (property_exists($this, $option)) {
             $this->{$option} = $value;
         } else {
             $this->attributes[$option] = $value;
         }
     }
 }
示例#7
0
 /**
  * Construct the Text object and convert $text to UTF-8.
  *
  * @param string       $text    The text
  * @param string|array $charset string: The charset of $text; array: Autodetect encoding, example: array('ASCII', 'UTF-8', 'ISO-8859-15'); null: defaults to Framework::$charset
  */
 public function __construct($text, $charset = null)
 {
     if ($text instanceof self) {
         $this->text = $text->text;
         if ($charset !== null && $charset !== 'UTF-8') {
             \Sledgehammer\notice('Invalid charset given, an Text object will alway be UTF-8 encoded');
         }
         return;
     }
     if ($charset === null) {
         $charset = Framework::$charset;
     } elseif (is_array($charset)) {
         $charset = mb_detect_encoding($text, $charset, true);
         if ($charset === false) {
             \Sledgehammer\notice('Unable to detect charset');
             $this->text = mb_convert_encoding($text, 'UTF-8');
             return;
         }
     }
     $this->text = mb_convert_encoding($text, 'UTF-8', $charset);
 }
示例#8
0
文件: Form.php 项目: sledgehammer/mvc
 public function import(&$errors = null, $request = null)
 {
     $this->state = 'NOT_SENT';
     if ($request === null) {
         if (strtolower($this->getAttribute('method')) === 'post') {
             $request = $_POST;
         } elseif (strtolower($this->getAttribute('method')) === 'get') {
             $request = $_GET;
         } else {
             \Sledgehammer\notice('Unexpected method: "' . $this->getAttribute('method') . '"');
             $request = $_REQUEST;
         }
     }
     if (count($request) == 0) {
         return $this->getValue();
     }
     $this->state = 'SENT';
     $data = [];
     foreach ($this->fields as $key => $field) {
         if (is_object($field) && method_exists($field, 'import')) {
             $data[$key] = $field->import($error, $request);
             if ($error) {
                 $errors[$key] = $error;
             }
         }
     }
     if (empty($data['actions'])) {
         // import which input type="submit" is sent.
         foreach ($this->actions as $component) {
             if (is_object($component) && method_exists($component, 'import')) {
                 if (empty($data['actions'])) {
                     $data['actions'] = [];
                 }
                 $data['actions'][$key] = $component->import($_, $request);
             }
         }
     }
     return $data;
 }
示例#9
0
}
$targets = array('php' => \Sledgehammer\PATH . 'vendor/pear/php', 'data' => \Sledgehammer\PATH . 'vendor/pear/data', 'script' => \Sledgehammer\PATH . 'vendor/pear/script', 'bin' => \Sledgehammer\PATH . 'vendor/pear/bin', 'doc' => \Sledgehammer\PATH . 'vendor/pear/docs', 'www' => APP_DIR . 'vendor/pear/www');
$pear = new PearInstaller($targets);
$pear->on('channelAdded', function ($sender, $domain, $channel) {
    echo 'Channel "' . $domain . '" loaded. (' . count($channel['packages']) . " packages)\n";
});
$pear->on('installed', function ($sender, $package, $version) {
    echo '  ' . $package . ' [' . $version . "] installed.\n";
});
unset($argv[0]);
foreach ($argv as $arg) {
    if (preg_match('/^((?P<channel>[^\\/]+)\\/){0,1}(?P<package>[^\\/-]+){1}(\\-(?P<version>[0-9\\.]+|alpha|beta|stable)){0,1}$/', $arg, $matches)) {
        //|-stable|-alpha|-beta
        if ($matches['channel'] == '' && empty($matches['version']) && preg_match('/^([a-z0-9]+\\.)+[a-z]{2,4}$/i', $arg)) {
            // "pear.php.net"
            $pear->addChannel($arg);
        } else {
            $options = [];
            if (empty($matches['channel']) == false) {
                $options['channel'] = $matches['channel'];
            }
            if (isset($matches['version'])) {
                $options['version'] = $matches['version'];
            }
            $pear->install($matches['package'], $options);
        }
    } else {
        \Sledgehammer\notice('Unable to determine package-name in "' . $arg . '"');
        // A package name containing a "/" or -" ?
    }
}
示例#10
0
 /**
  * Extract class and interface definitions from a file.
  *
  * @param string $filename Fullpath to the php-file.
  */
 public function open($filename)
 {
     $tokens = new PhpTokenizer(file_get_contents($filename));
     $namespace = '';
     $uses = [];
     $definitions = [];
     $definition = array('level' => -1);
     $globalFunctions = [];
     $functions =& $globalFunctions;
     $level = 0;
     $parameterLevel = -1;
     // skip parameters in anonymous functions
     foreach ($tokens as $token) {
         $type = $token[0];
         $value = $token[1];
         if ($value == '' && $type != 'T_NAMESPACE') {
             \Sledgehammer\notice('Empty token', $token);
         }
         if ($type == 'T_PHP' || $type == 'T_HTML') {
             continue;
         }
         switch ($type) {
             case 'T_NAMESPACE':
                 $namespace = $value;
                 break;
             case 'T_USE':
                 $pos = strrpos($value, '\\');
                 $namespaceAlias = $pos === false ? $value : substr($value, $pos + 1);
                 $uses[$namespaceAlias] = $value;
                 break;
             case 'T_USE_ALIAS':
                 $uses[$value] = $uses[$namespaceAlias];
                 unset($uses[$namespaceAlias]);
                 break;
             case 'T_INTERFACE':
                 $definitions[] = array('type' => 'INTERFACE', 'namespace' => $namespace, 'interface' => $value, 'identifier' => $this->prefixNamespace($namespace, $value, $uses), 'extends' => [], 'methods' => [], 'level' => $level);
                 $definition =& $definitions[count($definitions) - 1];
                 break;
             case 'T_CLASS':
                 $definitions[] = array('type' => 'CLASS', 'namespace' => $namespace, 'class' => $value, 'identifier' => $this->prefixNamespace($namespace, $value, $uses), 'extends' => [], 'implements' => [], 'methods' => [], 'level' => $level);
                 $definition =& $definitions[count($definitions) - 1];
                 break;
             case 'T_EXTENDS':
                 $extends = $this->prefixNamespace($namespace, $value, $uses);
                 $definition['extends'][] = $extends;
                 $this->addUsedIn($extends, $filename, $token[2]);
                 break;
             case 'T_IMPLEMENTS':
                 $interface = $this->prefixNamespace($namespace, $value, $uses);
                 $definition['implements'][] = $interface;
                 $this->addUsedIn($interface, $filename, $token[2]);
                 break;
             case 'T_FUNCTION':
                 $function = $value;
                 $parameter = null;
                 if ($level == $definition['level'] + 1) {
                     $definition['methods'][$function] = [];
                     $functions =& $definition['methods'];
                 } else {
                     $functions =& $globalFunctions;
                 }
                 $parameterLevel = $level;
                 break;
             case 'T_TYPE_HINT':
                 if (strtolower($value) !== 'array') {
                     $this->addUsedIn($this->prefixNamespace($namespace, $value, $uses), $filename, $token[2]);
                 }
                 break;
             case 'T_PARAMETER':
                 if ($parameterLevel != $level) {
                     // Doesn't this parameter belong to the function?
                     break;
                     // Propably a catch () parameter
                 }
                 $parameter = substr($value, 1);
                 // strip '$'
                 $functions[$function][$parameter] = null;
                 break;
             case 'T_PARAMETER_VALUE':
                 $functions[$function][$parameter] = $value;
                 $parameter = null;
                 break;
             case 'T_OPEN_BRACKET':
                 $level++;
                 break;
             case 'T_CLOSE_BRACKET':
                 $level--;
                 break;
             case 'T_CALL':
                 $this->addCalledIn($value, $filename, $token[2]);
                 break;
             case 'T_METHOD_CALL':
                 break;
             case 'T_OBJECT':
                 $this->addUsedIn($this->prefixNamespace($namespace, $value, $uses), $filename, $token[2]);
                 break;
             default:
                 \Sledgehammer\notice('Unexpected tokenType: "' . $type . '"');
                 break;
         }
     }
     if ($level != 0) {
         \Sledgehammer\notice('Level: ' . $level . ' Number of "{" doesn\'t match the number of "}"');
     }
     unset($definition);
     // Add definitions to de loader
     foreach ($definitions as $index => $definition) {
         $identifier = $definition['identifier'];
         unset($definition['identifier'], $definition['level']);
         $definition['filename'] = $filename;
         //			$duplicate = false;
         //			if (isset($this->classes[$identifier])) {
         //				$duplicate = $this->classes[$identifier];
         //			} elseif (isset($this->interfaces[$identifier])) {
         //				$duplicate = $this->interfaces[$identifier];
         //			}
         //			if ($duplicate) {
         //				$this->parserNotice('"'.$identifier.'" is ambiguous, it\'s found in multiple files: "'.$duplicate['filename'].'" and "'.$definition['filename'].'"');
         //			}
         switch ($definition['type']) {
             case 'CLASS':
                 unset($definition['type']);
                 if (count($definition['extends']) > 1) {
                     \Sledgehammer\notice('Class: "' . $definition['class'] . '" Multiple inheritance is not allowed for classes');
                     $definition['extends'] = $definition['extends'][0];
                 } elseif (count($definition['extends']) == 1) {
                     $definition['extends'] = $definition['extends'][0];
                 } else {
                     unset($definition['extends']);
                 }
                 if (count($definition['implements']) == 0) {
                     unset($definition['implements']);
                 }
                 $this->classes[$identifier] = $definition;
                 break;
             case 'INTERFACE':
                 unset($definition['type']);
                 $this->interfaces[$identifier] = $definition;
                 break;
             default:
                 throw new Exception('Unsupported type: "' . $definition['type'] . '"');
         }
     }
 }
示例#11
0
 /**
  * The object is used as an string.
  *
  * @return string
  */
 public function __toString()
 {
     \Sledgehammer\notice('Object: "' . get_class($this) . '" is used as string');
     return 'Object(' . get_class($this) . ')';
 }
示例#12
0
文件: Csv.php 项目: sledgehammer/core
 /**
  * De rij inlezen en naar de volgende regel gaan.
  *
  * @link http://php.net/manual/en/iterator.next.php
  */
 public function next()
 {
     $this->values = [];
     $row = fgetcsv($this->fp, 0, $this->delimiter, $this->enclosure);
     if ($row) {
         // Is het einde (eof) nog niet bereikt?
         if ($row === array(null)) {
             // Empty row?
             return $this->next();
             // Skip row
         }
         ++$this->index;
         foreach ($this->keys as $index => $key) {
             if (isset($row[$index])) {
                 // Is er voor deze kolom een waarde?
                 $this->values[$key] = $row[$index];
             } else {
                 $filename = strpos($this->filename, \Sledgehammer\PATH) === 0 ? substr($this->filename, strlen(\Sledgehammer\PATH)) : $this->filename;
                 // Waar mogelijk het PATH er van af halen
                 \Sledgehammer\notice('Row too short, missing column #' . ($index + 1) . ': "' . $this->keys[$index] . '" in ' . $filename . ' on line ' . ($this->index + 2), $row);
                 // @todo Calculate line offset compared to the index ()
             }
         }
     } else {
         $this->index = null;
     }
 }
示例#13
0
 /**
  * Constructor.
  *
  * @param string $contents The contents of a php script/file
  */
 public function __construct($contents)
 {
     $previousError = error_get_last();
     $this->tokens = token_get_all($contents);
     $error = error_get_last();
     if ($error !== $previousError) {
         \Sledgehammer\notice($error['type'], $error['message']);
     }
 }
示例#14
0
 /**
  * Store the value in the cache.
  *
  * @param mixed      $value   The value
  * @param string|int $expires expires  A string is parsed via strtotime(). Examples: '+5min' or '2020-01-01' int's larger than 3600 (1 hour) are interpreted as unix timestamp expire date. And int's smaller or equal to 3600 are interpreted used as ttl.
  */
 protected function write($value, $expires = false)
 {
     if ($expires !== false) {
         if (is_string($expires)) {
             $expires = strtotime($expires);
         }
         if ($expires <= 3600) {
             // Is a ttl?
             $expires += time();
         } elseif ($expires < time()) {
             \Sledgehammer\notice('Writing an expired cache entry', 'Use Cache->clear() to invalidate a cache entry');
         }
     }
     $method = $this->_backend . '_write';
     $this->{$method}($value, $expires);
 }
示例#15
0
 /**
  * Converts the tokens into a parsed path.
  *
  * @param string $tokens
  *
  * @return array
  */
 public static function parse($path)
 {
     // Check if the path is cached
     static $cache = [];
     if (isset($cache[$path])) {
         return $cache[$path];
     }
     $tokens = self::tokenize($path);
     if (count($tokens) === 0) {
         \Sledgehammer\notice('Path is empty');
         return false;
     }
     $compiled = [];
     $length = count($tokens);
     $first = true;
     for ($i = 0; $i < $length; ++$i) {
         $token = $tokens[$i];
         if ($i + 1 === $length) {
             $nextToken = array('T_END', '');
         } else {
             $nextToken = $tokens[$i + 1];
         }
         switch ($token[0]) {
             // TYPE_ANY
             case self::T_STRING:
                 if ($first === false) {
                     // Invalid chain? "[el]any" instead of "[el].any"
                     \Sledgehammer\notice('Invalid chain, expecting a ".", "->" or "[" before "' . $token[1] . '"');
                     return false;
                 }
                 if ($nextToken[0] === self::T_OPTIONAL) {
                     $compiled[] = array(self::TYPE_OPTIONAL, $token[1]);
                     ++$i;
                 } else {
                     $compiled[] = array(self::TYPE_ANY, $token[1]);
                 }
                 break;
                 // Chained T_ANY
             // Chained T_ANY
             case self::T_DOT:
                 if ($first) {
                     if ($nextToken[0] !== 'T_END') {
                         \Sledgehammer\notice('Invalid "." in the path', 'Use "." for chaining, not at the beginning of a path');
                         return false;
                     }
                     $compiled[] = array(self::TYPE_SELF, $token[1]);
                     break;
                 }
                 if ($nextToken[0] !== self::T_STRING) {
                     \Sledgehammer\notice('Invalid "' . $token[1] . '" in path, expecting an identifier after "."');
                     return false;
                 }
                 if ($i + 2 !== $length && $tokens[$i + 2][0] === self::T_OPTIONAL) {
                     $compiled[] = array(self::TYPE_OPTIONAL, $nextToken[1]);
                     $i += 2;
                 } else {
                     $compiled[] = array(self::TYPE_ANY, $nextToken[1]);
                     ++$i;
                 }
                 break;
                 // TYPE_PROPERTY
             // TYPE_PROPERTY
             case self::T_ARROW:
                 if ($nextToken[0] !== self::T_STRING) {
                     \Sledgehammer\notice('Invalid "' . $token[1] . '" in path, expecting an identifier after an "->"');
                     return false;
                 }
                 if ($i + 2 !== $length && $tokens[$i + 2][0] === self::T_OPTIONAL) {
                     $compiled[] = array(self::TYPE_OPTIONAL_PROPERTY, $nextToken[1]);
                     $i += 2;
                 } else {
                     if (preg_match('/^[a-z_]{1}[a-z_0-9]*$/i', $nextToken[1]) != 1) {
                         \Sledgehammer\notice('Invalid property identifier "' . $nextToken[1] . '" in path "' . $path . '"');
                     }
                     $compiled[] = array(self::TYPE_PROPERTY, $nextToken[1]);
                     ++$i;
                 }
                 break;
                 // TYPE_ELEMENT
             // TYPE_ELEMENT
             case self::T_BRACKET_OPEN:
                 if ($nextToken[0] !== self::T_STRING) {
                     \Sledgehammer\notice('Unexpected token "' . $token[0] . '" in path, expecting T_STRING after ".["', $token);
                     return false;
                 }
                 if ($i + 2 === $length) {
                     \Sledgehammer\notice('Unmatched brackets, missing a "]" in path after "' . $nextToken[1] . '"');
                     return false;
                 }
                 if ($tokens[$i + 2][0] === self::T_OPTIONAL) {
                     if ($i + 2 === $length || $tokens[$i + 3][0] !== self::T_BRACKET_CLOSE) {
                         \Sledgehammer\notice('Unmatched brackets, missing a "]" in path after "' . $nextToken[1] . '?"');
                         return false;
                     }
                     $compiled[] = array(self::TYPE_OPTIONAL_ELEMENT, $nextToken[1]);
                     $i += 3;
                 } else {
                     if ($tokens[$i + 2][0] !== self::T_BRACKET_CLOSE) {
                         \Sledgehammer\notice('Unmatched brackets, missing a "]" in path after "' . $nextToken[1] . '"');
                         return false;
                     }
                     $compiled[] = array(self::TYPE_ELEMENT, $nextToken[1]);
                     $i += 2;
                 }
                 break;
             case self::T_ALL_ELEMENTS:
                 // [*]
                 if ($nextToken[0] === self::T_STRING) {
                     \Sledgehammer\notice('Invalid chain, expecting a ".", "->" or "[" before "' . $nextToken[1] . '"');
                     return false;
                 }
                 $offset = $i + 1;
                 if ($nextToken[0] === self::T_DOT) {
                     ++$offset;
                     // skip the dot to prevent "Invalid beginning error"
                 }
                 // Merge remaining tokens as subpath
                 $subpath = '';
                 $tokens = array_slice($tokens, $offset);
                 foreach ($tokens as $token) {
                     $subpath .= $token[1];
                 }
                 $compiled[] = array(self::TYPE_SUBPATH, $subpath);
                 return $compiled;
             default:
                 \Sledgehammer\notice('Unexpected token: "' . $token[0] . '"');
                 return false;
         }
         $first = false;
     }
     $cache[$path] = $compiled;
     return $compiled;
 }
示例#16
0
 /**
  * Report the notice but prevent the (Laravel) error_handler to throw an exception.
  */
 private static function hint($message, $information = null)
 {
     $handler = set_error_handler('error_log');
     restore_error_handler();
     if ($handler !== null) {
         if (is_array($handler) && is_object($handler[0]) && $handler[0] instanceof \Illuminate\Foundation\Bootstrap\HandleExceptions) {
             \Illuminate\Support\Facades\Log::notice($message);
         } else {
             \Sledgehammer\notice($message, $information);
         }
     }
 }
示例#17
0
 /**
  * Callback voor exceptions die buiten een try/catch block ge-throw-t worden.
  *
  * @param Exception $exception
  */
 public function exceptionCallback($exception)
 {
     if (self::isThrowable($exception)) {
         if (count(debug_backtrace()) == 1) {
             // An uncaught exception? via the set_exception_handler()
             self::instance()->report($exception, '__UNCAUGHT_EXCEPTION__');
         } else {
             \Sledgehammer\notice('Only the set_exception_handler() should call ErrorHandler->exceptionCallback. use \\Sledgehammer\\report_exception()', 'Use the <b>report_exception</b>($exception) for reporting to the default Errorhandler.<br />Or call the ErrorHander->report($exception) to target a specific instance.');
             self::instance()->report($exception);
         }
     } else {
         self::report(E_USER_ERROR, 'Parameter $exception must be an Exception, instead of a ' . gettype($exception));
     }
 }
示例#18
0
 /**
  * Build a closure which validates an item with the gives $conditions.
  *
  * @param mixed $conditions array|Closure|expression  See Collection::where() for condition options
  *
  * @return callable
  */
 protected function buildFilter($conditions)
 {
     if (\Sledgehammer\is_closure($conditions)) {
         return $conditions;
     }
     if (is_array($conditions)) {
         // Create filter that checks all conditions
         $logicalOperator = \Sledgehammer\extract_logical_operator($conditions);
         if ($logicalOperator === false) {
             if (count($conditions) > 1) {
                 \Sledgehammer\notice('Conditions with multiple conditions require a logical operator.', "Example: array('AND', 'x' => 1, 'y' => 5)");
             }
             $logicalOperator = 'AND';
         } else {
             unset($conditions[0]);
         }
         $operators = [];
         foreach ($conditions as $path => $expectation) {
             if (preg_match('/^(.*) (' . \Sledgehammer\COMPARE_OPERATORS . ')$/', $path, $matches)) {
                 unset($conditions[$path]);
                 $conditions[$matches[1]] = $expectation;
                 $operators[$matches[1]] = $matches[2];
             } else {
                 $operators[$path] = false;
             }
         }
         // @todo Build an optimized closure for when a single conditions is given.
         if ($logicalOperator === 'AND') {
             return function ($item) use($conditions, $operators) {
                 foreach ($conditions as $path => $expectation) {
                     $actual = PropertyPath::get($path, $item);
                     $operator = $operators[$path];
                     if ($operator) {
                         if (\Sledgehammer\compare($actual, $operator, $expectation) === false) {
                             return false;
                         }
                     } elseif (\Sledgehammer\equals($actual, $expectation) === false) {
                         return false;
                     }
                 }
                 return true;
                 // All conditions are met.
             };
         } elseif ($logicalOperator === 'OR') {
             return function ($item) use($conditions, $operators) {
                 foreach ($conditions as $path => $expectation) {
                     $actual = PropertyPath::get($path, $item);
                     $operator = $operators[$path];
                     if ($operator) {
                         if (\Sledgehammer\compare($actual, $operator, $expectation) !== false) {
                             return true;
                         }
                     } elseif (\Sledgehammer\equals($actual, $expectation) !== false) {
                         return true;
                     }
                 }
                 return false;
                 // None of conditions are met.
             };
         } else {
             throw new Exception('Unsupported logical operator "' . $logicalOperator . '", expecting "AND" or "OR"');
         }
     }
     //'<= 5' or '10'
     // Compare the item directly with value given as $condition.
     if (is_string($conditions) && preg_match('/^(' . \Sledgehammer\COMPARE_OPERATORS . ') (.*)$/', $conditions, $matches)) {
         $operator = $matches[1];
         $expectation = $matches[2];
     } else {
         $expectation = $conditions;
         $operator = '==';
     }
     return function ($value) use($expectation, $operator) {
         return \Sledgehammer\compare($value, $operator, $expectation);
     };
 }
示例#19
0
 /**
  * Download and install a PEAR package.
  *
  * @throws Exceptions on failure
  *
  * @param string $package
  * @param string $version
  * @param array  $options array(
  *                        'version' = Install a specific version
  *                        'target' => alternative target directory
  *                        'channel' => specifiy the channel
  *                        )
  */
 public function install($package, $options = [])
 {
     $version = \Sledgehammer\array_value($options, 'version') ?: 'stable';
     if (isset($options['channel'])) {
         $channel = $options['channel'];
         $this->addChannel($channel);
         if (empty($this->channels[$channel]['packages'][$package])) {
             if (isset($this->channels[$channel]['packages'])) {
                 foreach ($this->channels[$channel]['packages'] as $name => $info) {
                     if (strcasecmp($name, $package) === 0) {
                         return $this->install($name, $options);
                     }
                 }
             }
             throw new InfoException('Package "' . $package . '" not found in channel: ' . $channel, \Sledgehammer\quoted_human_implode(' and ', array_keys($this->channels[$channel]['packages'])));
         }
         $packageLocation =& $this->channels[$channel]['packages'][$package];
     } else {
         if (count($this->channels) === 0) {
             $this->addChannel('pear.php.net');
         }
         if (empty($this->packages[$package])) {
             foreach ($this->packages as $name => $channel) {
                 if (strcasecmp($name, $package) === 0) {
                     return $this->install($name, $options);
                 }
             }
             throw new InfoException('Package "' . $package . '" not found in channels: ' . \Sledgehammer\quoted_human_implode(' and ', array_keys($this->channels)), 'Available packages: ' . \Sledgehammer\quoted_human_implode(' and ', array_keys($this->packages)));
         }
         $packageLocation =& $this->channels[$this->packages[$package]]['packages'][$package];
     }
     $release = $this->findRelease($packageLocation, $version);
     if (\Sledgehammer\array_value($packageLocation, 'installed') === $version) {
         return;
     }
     $this->trigger('installing', $this, $package, $version);
     $tmpFolder = \Sledgehammer\TMP_DIR . 'PearInstaller/';
     $folderName = $package . '-' . $version;
     $tarFile = $tmpFolder . $folderName . '/package.tar';
     \Sledgehammer\mkdirs(dirname($tarFile));
     if (file_exists($tarFile) === false) {
         // Is this package already in the tmp folder
         Curl::download($release->g . '.tar', $tarFile);
     }
     chdir(dirname($tarFile));
     system('tar xf ' . escapeshellarg($tarFile), $exit);
     if ($exit !== 0) {
         throw new Exception('Unable to untar "' . $tarFile . '"');
     }
     if (file_exists(dirname($tarFile) . '/package2.xml')) {
         $info = simplexml_load_file(dirname($tarFile) . '/package2.xml');
     } else {
         $info = simplexml_load_file(dirname($tarFile) . '/package.xml');
     }
     // Install dependencies first
     foreach ($info->dependencies->required->package as $dependancy) {
         if ($dependancy->conflicts) {
             //				\Sledgehammer\notice('Dependancy "'.$dependancy->name.'" for "'.$package.'" <conflicts />');
             continue;
         }
         $this->install((string) $dependancy->name, array('channel' => (string) $dependancy->channel));
     }
     $renames = [];
     foreach ($info->phprelease as $release) {
         if ($release->count() > 0) {
             foreach ($release->filelist->install as $move) {
                 $renames[(string) $move['name']] = (string) $move['as'];
             }
         }
     }
     $files = $this->extractFiles($info->contents->dir, '', '/', $renames);
     foreach ($files as $file) {
         if (isset($this->targets[$file['role']])) {
             $dir = $this->targets[$file['role']];
             if (in_array($file['role'], array('doc', 'www'))) {
                 if (\Sledgehammer\text($file['to'])->startsWith($package) == false) {
                     $dir = $this->makePath($dir, $package);
                 }
             }
             $target = $this->makePath($dir, $file['to']);
             if (\Sledgehammer\mkdirs(dirname($target)) == false || is_writable(dirname($target)) == false) {
                 throw new Exception('Target "' . $target . '" is not writable');
             }
             $source = $this->makePath($tmpFolder . $folderName . '/' . $folderName, $file['from']);
             if (isset($file['tasks'])) {
                 $contents = file_get_contents($source);
                 foreach ($file['tasks'] as $task) {
                     $value = null;
                     if ($task['type'] === 'package-info') {
                         if ($task['to'] == 'version') {
                             $value = $version;
                         } elseif ($task['to'] == 'state') {
                             $value = (string) $info->stability->release;
                         }
                     } elseif ($task['type'] == 'pear-config') {
                         if (substr($task['to'], -4) === '_dir') {
                             $role = substr($task['to'], 0, -4);
                             if (isset($this->targets[$role])) {
                                 $value = $this->targets[$role];
                                 // @todo calculate relative paths
                                 \Sledgehammer\notice('Harcoding path "' . $value . '" into "' . $file['to'] . '"', $file);
                             }
                         } elseif ($task['to'] == 'php_bin') {
                             $value = trim(`which php`);
                             \Sledgehammer\notice('Harcoding path "' . $value . '" into "' . $file['to'] . '"', $file);
                         }
                     }
                     if ($task['task'] === 'replace') {
                         if ($value != '') {
                             $contents = str_replace($task['from'], $value, $contents);
                         } else {
                             \Sledgehammer\notice($task['type'] . ' "' . $task['to'] . '" not yet supported');
                         }
                     } else {
                         \Sledgehammer\notice('task "' . $task['task'] . '" not implemented');
                     }
                 }
                 file_put_contents($target, $contents);
             } else {
                 copy($source, $target);
             }
         }
     }
     \Sledgehammer\rmdir_recursive($tmpFolder . $folderName . '/' . $folderName);
     $packageLocation['installed'] = $version;
     $this->trigger('installed', $this, $package, $version);
 }
示例#20
0
 /**
  * Return a subsection of the collection based on the conditions.
  *
  * Convert the $conditions to SQL object when appropriate.
  *
  * auto converts
  *   ['x_id' => null]  to "x_id IS NULL"
  * 	 ['x_id !=' => null]  to "x_id IS NOT NULL"
  *  'hits' => 0]  to "hits = '0'"  (Because in mysql '' = 0 evaluates to true, '' = '0' to false)
  *
  * @param array $conditions
  *
  * @return Collection
  */
 public function where($conditions)
 {
     if ($this->data !== null || is_string($this->sql) || is_object($conditions) && is_callable($conditions) || $this->sql->limit !== false || $this->sql->offset != 0) {
         return parent::where($conditions);
     }
     $db = Connection::instance($this->dbLink);
     $sql = $this->sql;
     $logicalOperator = \Sledgehammer\extract_logical_operator($conditions);
     if ($logicalOperator === false) {
         if (count($conditions) > 1) {
             \Sledgehammer\notice('Conditions with multiple conditions require a logical operator.', "Example: array('AND', 'x' => 1, 'y' => 5)");
         }
         $logicalOperator = 'AND';
     } else {
         unset($conditions[0]);
     }
     if ($logicalOperator === 'AND') {
         $method = 'andWhere';
     } elseif ($logicalOperator === 'OR') {
         $method = 'orWhere';
     } else {
         throw new Exception('Unsupported logical operator "' . $logicalOperator . '", expecting "AND" or "OR"');
     }
     // The result are rows(fetch_assoc arrays), all conditions must be columnnames (or invalid)
     foreach ($conditions as $path => $value) {
         if (preg_match('/^(.*) (' . \Sledgehammer\COMPARE_OPERATORS . ')$/', $path, $matches)) {
             $column = $this->convertPathToColumn($matches[1]);
             $operator = $matches[2];
         } else {
             $column = $this->convertPathToColumn($path);
             $operator = '==';
         }
         if ($column === false) {
             // Converting to path failed?
             \Sledgehammer\array_key_unshift($conditions, 0, $logicalOperator);
             return parent::where($conditions);
         }
         if ($value === null) {
             switch ($operator) {
                 case '==':
                     $operator = 'IS';
                     $expectation = 'NULL';
                     break;
                 case '!=':
                     $operator = 'IS NOT ';
                     $expectation = 'NULL';
                     break;
                 case '>':
                 case '<':
                 case '>=':
                 case '<=':
                     $expectation = "''";
                     break;
                 default:
                     \Sledgehammer\warning('Unknown behavior for NULL values with operator "' . $operator . '"');
                     $expectation = $db->quote($expectation);
                     break;
             }
             $sql = $sql->{$method}($column . ' ' . $operator . ' ' . $expectation);
         } else {
             if ($operator === '!=') {
                 $sql = $sql->{$method}('(' . $column . ' != ' . $db->quote($value, PDO::PARAM_STR) . ' OR ' . $column . ' IS NULL)');
             } elseif ($operator === 'IN') {
                 if ((is_array($value) || $value instanceof Traversable) === false) {
                     \Sledgehammer\notice('Operator IN expects an array or Traversable', $value);
                     $value = explode(',', $value);
                 }
                 $quoted = [];
                 foreach ($value as $val) {
                     $quoted[] = $this->quote($db, $column, $val);
                 }
                 $sql = $sql->{$method}($column . ' ' . $operator . ' (' . implode(', ', $quoted) . ')');
             } else {
                 if ($operator === '==') {
                     $operator = '=';
                 }
                 $sql = $sql->{$method}($column . ' ' . $operator . ' ' . $this->quote($db, $column, $value));
             }
         }
     }
     return new self($sql, $this->dbLink);
 }
示例#21
0
文件: Sql.php 项目: sledgehammer/core
 /**
  * Returns a new SQL with the $sql->where set to the given $where.
  *
  * @param string|array $where
  *
  * @return Sql
  */
 public function where($where)
 {
     $sql = clone $this;
     if ($sql->where !== '') {
         \Sledgehammer\notice('Overruling where');
     }
     $sql->where = $where;
     return $sql;
 }
示例#22
0
 /**
  * @param string $label
  * @param string $message
  * @param string $overwrite
  */
 public static function send($label, $message, $overwrite = false)
 {
     if (self::isEnabled() === false) {
         return;
     }
     if (preg_match('/^(?<label>[a-z0-9\\-]+)(?<suffix>\\.[0-9]+)?$/i', $label, $match) == false) {
         \Sledgehammer\notice('Label: "' . $label . '" in invalid', 'A label may contain number, letters and "-"');
         return;
     }
     $number = \Sledgehammer\array_value(self::$increments, $match['label']);
     if (isset($match['suffix'])) {
         // Has a suffix?
         $labelSuffix = $match[0];
         if ($overwrite === false) {
             \Sledgehammer\notice('Overwrite flag required for label: "' . $label . '"');
             return;
         }
         if ($number <= substr($match['suffix'], 1)) {
             self::$increments[$match['label']] = substr($match['suffix'], 1) + 1;
         }
     } elseif ($overwrite === false) {
         if ($number) {
             $label .= '.' . $number;
         }
         self::$increments[$match['label']] = $number + 1;
     }
     if (headers_sent($file, $line)) {
         if ($file == '' && $line == 0) {
             $location = '';
         } else {
             $location = ', output started in ' . $file . ' on line ' . $line;
         }
         \Sledgehammer\notice('Couldn\'t sent header(s)' . $location);
         return;
     }
     $value = base64_encode($message);
     $length = strlen($value);
     // Prevent 325 net::ERR_RESPONSE_HEADERS_TOO_BIG in Google Chrome.
     if (self::$bytesSent + $length >= 240000) {
         // >= 235KiB?
         if (self::$bytesSent < 239950) {
             call_user_func(self::$headerAdd, 'DebugR-' . $label . ': ' . base64_encode('DebugR: TOO_MUCH_DATA'));
         }
         return;
     }
     if ($length <= 4000) {
         // Under 4KB? (96B for the label)
         $header = 'DebugR-' . $label . ': ';
         call_user_func(self::$headerAdd, $header . $value);
         self::$bytesSent += strlen($header) + $length;
     } else {
         // Send in 4KB chunks.
         call_user_func(self::$headerRemove, 'DebugR-' . $label);
         $chunks = str_split($value, 4000);
         foreach ($chunks as $index => $chunk) {
             $header = 'DebugR-' . $label . '.chunk' . $index . ': ';
             call_user_func(self::$headerAdd, $header . $chunk);
             self::$bytesSent += strlen($header);
         }
         self::$bytesSent += $length;
     }
 }
示例#23
0
 /**
  * Report MySQL warnings and notes if any.
  *
  * @param Sql|string $statement
  */
 public function checkWarnings($statement)
 {
     if (isset($this->reportWarnings) && $this->reportWarnings === true) {
         $info = [];
         if ($statement instanceof Sql) {
             $info['SQL'] = (string) $statement;
         }
         $start = microtime(true);
         $this->previousInsertId = parent::lastInsertId();
         $warnings = parent::query('SHOW WARNINGS');
         if ($warnings === false) {
             $this->reportError('SHOW WARNINGS');
             return;
         }
         $this->logger->totalDuration += microtime(true) - $start;
         if ($warnings->rowCount()) {
             foreach ($warnings->fetchAll(PDO::FETCH_ASSOC) as $warning) {
                 \Sledgehammer\notice('SQL ' . strtolower($warning['Level']) . ' [' . $warning['Code'] . '] ' . $warning['Message'], $info);
             }
             // @todo Clear warnings
             // PDO/MySQL doesn't clear the warnings before CREATE/DROP DATABASE queries.
         }
     }
 }
示例#24
0
 /**
  * Limit the number of active transfers.
  *
  * @param int $max The allowed number of active connections.
  *
  * @throws Exception
  */
 private static function throttle($max)
 {
     if (self::$pool === null) {
         return;
     }
     $max = intval($max);
     if ($max < 0) {
         \Sledgehammer\notice('Invalid throttle value: ' . $max);
         $max = 0;
     }
     if (count(self::$requests) <= $max) {
         return;
     }
     do {
         // Wait for (incomming) data
         if (curl_multi_select(self::$pool, 0.2) === -1) {
             usleep(100000);
             // wait 0.1 second
         }
         $activeTransfers = 0;
         foreach (self::$requests as $curl) {
             if ($curl->isComplete() == false) {
                 ++$activeTransfers;
             }
         }
     } while ($activeTransfers > $max);
 }