Beispiel #1
0
 /**
  * Interpolates a multi-dimensional array with another array recursively
  *
  * If no source is given, you get a live interpolation where you can directly interpolate
  * variables that have just been interpolated before
  *
  * Don't fetch the return value, the arrays are references.
  * If you want an unmutable version, rather take ArrayUtil::interpolate
  *
  * This is mostly used for option arrays, e.g. config-files
  *
  * We take both arrays as a reference to achieve a live-interpolation effect.
  * You can work with values you just interpolated before
  * e.g. [ 'path' => '{{rootPath}}/my/path', 'subPaths' => [ '{{path}}/sub/path' ] ]
  *
  * If you want to keep the original array, take a copy before
  *
  * @param array      $array        The array to interpolate (Passed by reference)
  * @param array|null $source       The source array for variables. If none given, the input array is taken
  * @param null       $defaultValue The default value for indices that couldnt be resolved
  * @param string     $delimeter    The delimeter used for multi-dimension access (Default: Dot (.))
  *
  * @return array The interpolated array (Notice that it's just the same reference to the array you passed
  */
 public static function interpolateMutable(array &$array, array &$source = null, $defaultValue = null, $delimeter = null)
 {
     if (!$source) {
         $source =& $array;
     }
     $newKeys = [];
     foreach ($array as $key => &$val) {
         if (is_string($key)) {
             $newKey = StringUtil::interpolate($key, $source, $defaultValue, $delimeter);
             if ($key !== $newKey) {
                 $newKeys[$key] = $newKey;
             }
         }
         if (is_array($val)) {
             self::interpolateMutable($val, $source, $defaultValue, $delimeter);
         } else {
             if (is_string($val)) {
                 $array[$key] = StringUtil::interpolate($val, $source, $defaultValue, $delimeter);
             }
         }
     }
     foreach ($newKeys as $key => $newKey) {
         $array[$newKey] = $array[$key];
         unset($array[$key]);
     }
     return $array;
 }
Beispiel #2
0
 private static function _setPhpOptions()
 {
     $options = Config::get('php-options', []);
     foreach ($options as $name => $value) {
         ini_set(StringUtil::dasherize($name, '.'), $value);
     }
 }
Beispiel #3
0
 public function __construct($controller, $action, $format, array $args = null)
 {
     parent::__construct($format);
     //Sanitize names for consistent use
     $this->_controller = implode('.', array_map('Tale\\Util\\StringUtil::canonicalize', explode('.', $controller)));
     $this->_action = StringUtil::canonicalize($action);
     $this->_args = $args ? $args : [];
 }
Beispiel #4
0
 public static function getHeaders()
 {
     foreach ($_SERVER as $name => $value) {
         if (strncmp($name, 'HTTP_', 5) === 0) {
             $name = StringUtil::dasherize(StringUtil::humanize(strtolower(substr($name, 5))));
             (yield $name => $value);
         }
     }
 }
 public function setCanonicalNameFromName()
 {
     $name = null;
     $i = 0;
     do {
         $addOn = ++$i >= 2 ? "-{$i}" : '';
         $name = StringUtil::canonicalize($this->name) . $addOn;
     } while ($this->getTable()->where(['canonicalName' => $name])->count() > 0);
     $this->canonicalName = $name;
     return $name;
 }
Beispiel #6
0
 public static function get($key = null, $default = null)
 {
     if (!$key) {
         return self::$_options;
     }
     if (strpos($key, '.') !== false) {
         if (!isset(self::$_resolvedOptions[$key])) {
             self::$_resolvedOptions[$key] = StringUtil::resolve($key, self::$_options, $default);
         }
         return self::$_resolvedOptions[$key];
     }
     return isset(self::$_options[$key]) ? self::$_options[$key] : $default;
 }
 public function resolveOption($key, $default = null, $delimeter = null)
 {
     return StringUtil::resolve($key, $this->getConfig()->getItems(), $default, $delimeter);
 }
Beispiel #8
0
 private function _setPhpOptions()
 {
     foreach ($this->getOption('phpOptions') as $option => $value) {
         $option = StringUtil::tableize($option, '.');
         ini_set($option, $value);
     }
 }
Beispiel #9
0
 public function resolveMethodName($methodName)
 {
     return sprintf($this->_methodNamePattern, strpos($this->_methodNamePattern, '%s') === 0 ? StringUtil::variablize($methodName) : StringUtil::camelize($methodName));
 }
Beispiel #10
0
 public static function fromString($string)
 {
     $parts = StringUtil::mapReverse($string, ':', ['port', 'ip']);
     return new static(Address::fromString(trim($parts['ip'], '[]')), $parts['port']);
 }
Beispiel #11
0
 public static function dispatch(array $request = null)
 {
     $request = array_replace(['module' => null, 'controller' => self::DEFAULT_CONTROLLER, 'action' => self::DEFAULT_ACTION, 'id' => null, 'args' => [], 'format' => self::DEFAULT_FORMAT], $request ? $request : []);
     //Sanitize (e.g. you can pass [sS]ome[-_][cC]ontroller, we want some-controller)
     $request['controller'] = StringUtil::canonicalize($request['controller']);
     $request['action'] = StringUtil::canonicalize($request['action']);
     $request['format'] = strtolower($request['format']);
     if ($request['id']) {
         array_unshift($request['args'], $request['id']);
     }
     $className = self::getClassName($request['controller'], $request['module']);
     $methodName = self::getMethodName($request['action']);
     var_dump("DISPATCH {$className}->{$methodName}", $request);
     try {
         if (!class_exists($className) || !is_subclass_of($className, __CLASS__)) {
             throw new \Exception("Failed to dispatch controller: {$className} doesnt exist or is not an instance of " . __CLASS__);
         }
         if (!method_exists($className, $methodName)) {
             throw new \Exception("Failed to dispatch action: {$className} has no method {$methodName}");
         }
     } catch (\Exception $e) {
         if ($request['controller'] === self::ERROR_CONTROLLER) {
             throw $e;
         }
         self::dispatchError('not-found', array_merge(['exception' => $e], $request));
         return;
     }
     $controller = new $className($request);
     //Get controllers init* methods
     $initMethods = call_user_func([$className, 'getInitMethodNames']);
     //Call all init*-Methods
     $result = null;
     foreach ($initMethods as $method) {
         $result = call_user_func([$controller, $method]);
         if ($result) {
             break;
         }
     }
     //Call the action
     if (!$result) {
         $result = call_user_func_array([$controller, $methodName], $request['args']);
     }
     //Let the dev be able to change the format in the action
     $format = $controller->format;
     switch ($format) {
         default:
         case 'html':
             header('Content-Type: text/html; encoding=utf-8');
             $view = $controller->controller . '/' . $controller->action;
             if (!empty($controller->module)) {
                 $view = $controller->module . '/' . $view;
             }
             $path = $view . '.phtml';
             break;
         case 'json':
             header('Content-Type: application/json; encoding=utf-8');
             echo json_encode($result);
             break;
         case 'txt':
             header('Content-Type: text/plain; encoding=utf-8');
             echo serialize($result);
             break;
         case 'xml':
             header('Content-Type: text/xml; encoding=utf-8');
             $doc = new \DOMDocument('1.0', 'UTF-8');
             $doc->formatOutput = true;
             $addNode = function (\DOMNode $node, $name, $value, $self) use($doc) {
                 $type = gettype($value);
                 $el = $doc->createElement($name);
                 $typeAttr = $doc->createAttribute('type');
                 $typeAttr->value = $type;
                 $el->appendChild($typeAttr);
                 switch (strtolower($type)) {
                     case 'null':
                         $el->textContent = 'null';
                         break;
                     case 'string':
                     case 'int':
                     case 'double':
                         $el->textContent = (string) $value;
                         break;
                     case 'boolean':
                         $el->textContent = $value ? 'true' : 'false';
                         break;
                     case 'object':
                         if ($value instanceof XmlSerializable) {
                             $value = $value->xmlSerialize();
                         } else {
                             $value = (array) $value;
                         }
                     case 'array':
                         foreach ($value as $key => $val) {
                             $self($el, $key, $val, $self);
                         }
                         break;
                     case 'resource':
                         $el->textContent = get_resource_type($value);
                         break;
                 }
             };
             $addNode($doc, 'value', $result, $addNode);
             echo $doc->saveXML();
             break;
     }
 }
Beispiel #12
0
 public static function fromString($string)
 {
     $parts = StringUtil::mapReverse($string, ':', ['password', 'userName']);
     return new static($parts['userName'], $parts['password']);
 }
Beispiel #13
0
 /**
  * Interpolates {{var.subVar}}-style based on a source array given
  *
  * Dimensions in the source array are accessed with a passed delimeter (Default: Dot (.))
  *
  * @param string $string The input string to operate on
  * @param array $source The associative source array
  * @param mixed $defaultValue The default value for indices that dont exist
  * @param string|null $delimeter The delimeter for multi-dimension access (Default: Dot (.))
  *
  * @return string The interpolated string with the variables replaced with their values
  */
 public static function interpolate($string, array $source, $defaultValue = null, $delimeter = null)
 {
     return preg_replace_callback('/\\{\\{([^\\}]+)\\}\\}/i', function ($m) use($source, $defaultValue, $delimeter) {
         $resolved = StringUtil::resolve($m[1], $source, $defaultValue, $delimeter);
         if ($resolved === null) {
             return $m[0];
         }
         return $resolved;
     }, $string);
 }
Beispiel #14
0
 public function init()
 {
     $this->prependOptions(['defaultController' => 'index', 'defaultAction' => 'index', 'defaultId' => null, 'defaultFormat' => 'html', 'formats' => ['html', 'json'], 'routeOnRun' => true, 'baseUrl' => null, 'routes' => ['/:controller?/:action?/:id?.:format?' => ["@router", 'dispatchController']]]);
     $app = $this->getApp();
     $app->bind('beforeRun', function () {
         $routes = $this->getOption('routes');
         //Parse route targets
         foreach ($routes as $route => $callback) {
             if (is_array($callback) && is_string($callback[0])) {
                 $target = $callback[0];
                 if ($target[0] !== '@') {
                     break;
                 }
                 $handler = $callback[1];
                 $target = substr($target, 1);
                 switch ($target) {
                     case 'router':
                         $routes[$route][0] = $this;
                         break;
                     default:
                         $routes[$route] = function (array $routeData) use($target, $handler) {
                             $routeData = call_user_func([$target, $handler], $routeData);
                             return $this->dispatchController($routeData);
                         };
                 }
             }
         }
         if (isset($this->controller)) {
             /**
              * @var \Tale\App\Feature\Controller $controller
              */
             $controller = $this->controller;
             $controller->registerHelper('getUrl', function ($controller, $path = null, array $args = null, $preserveQuery = false) {
                 $path = $path ? $path : '';
                 if (isset($controller->request)) {
                     /**
                      * @var \Tale\App\Feature\Controller\Request $req
                      */
                     $req = $controller->request;
                     $path = StringUtil::interpolate($path, ['controller' => $req->getController(), 'action' => $req->getAction(), 'args' => $req->getArgs(), 'format' => $req->getFormat()]);
                 }
                 $url = $path;
                 $baseUrl = $this->getOption('baseUrl');
                 if ($baseUrl) {
                     $url = rtrim($baseUrl, '/') . '/' . ltrim($path, '/');
                 }
                 $query = [];
                 if ($args) {
                     $query = $args;
                 }
                 if ($preserveQuery && isset($controller->webRequest)) {
                     $query = array_replace_recursive($controller->webRequest->getUrlArgs(), $query);
                 }
                 if (!empty($query)) {
                     $url .= '?' . http_build_query($query);
                 }
                 return $url;
             });
             $controller->registerHelper('redirect', function ($controller, $path, array $args = null, $preserveQuery = null) {
                 return new Controller\Response\Redirect($controller->getUrl($path, $args, $preserveQuery));
             });
         }
         $this->_router = new AppRouter($routes);
     });
     $app->bind('run', function () use($app) {
         if ($this->getOption('routeOnRun')) {
             if ($app->isCliApp()) {
                 $this->routeCliRequest();
             } else {
                 $response = $this->routeHttpServerRequest();
                 $response->apply();
             }
         }
     });
     $app->bind('afterRun', function () {
         unset($this->_router);
     });
 }
Beispiel #15
0
 public static function getHeadersFromEnvironment()
 {
     self::_validateWebEnvironment();
     foreach ($_SERVER as $name => $value) {
         if (strncmp($name, 'HTTP_', 5) === 0) {
             $name = StringUtil::dasherize(StringUtil::humanize(strtolower(substr($name, 5))));
             (yield $name => $value);
         }
     }
 }
Beispiel #16
0
 public function renderView($path, array $args = null, $cacheHtml = false)
 {
     $renderView = function () use($path, $args) {
         $phtml = $this->fetchCached('views.' . StringUtil::canonicalize($path), function () use($path) {
             return $this->getConvertedContent(self::TYPE_VIEW, $path);
         }, $this->getOption('lifeTime'));
         if (!$phtml) {
             throw new \Exception("Failed to convert theme: Neither {$path} nor" . " any convertible file could be found");
         }
         $dataUri = "{$this->_wrapperName}://data;{$phtml}";
         $render = function ($__dataUri, $__args) {
             ob_start();
             extract($__args);
             include $__dataUri;
             return ob_get_clean();
         };
         return $render($dataUri, $args ? $args : []);
     };
     if (!$cacheHtml) {
         return $renderView();
     }
     return $this->fetchCached('views.html.' . StringUtil::canonicalize($path), $renderView, $this->getOption('lifeTime'));
 }
Beispiel #17
0
 public function __call($method, array $args = null)
 {
     if (!strlen($method) < 4) {
         $args = $args ? $args : [];
         $token = substr($method, 0, 3);
         if (in_array($token, ['has', 'get', 'set', 'add'])) {
             $name = substr($method, 3);
             $suffix = '';
             if (strlen($name) > 5 && substr($name, -5) === 'Array') {
                 $name = substr($name, 0, -5);
                 $suffix = 'Array';
             }
             $plural = StringUtil::pluralize($name);
             $singular = $plural !== $name;
             $table = $this->getDatabase()->{$plural};
             array_unshift($args, $table);
             switch (substr($method, 0, 3)) {
                 case 'has':
                     if ($singular) {
                         return call_user_func_array([$this, 'countOne'], $args) ? true : false;
                     }
                     return call_user_func_array([$this, 'countMany'], $args) ? true : false;
                 case 'get':
                     if ($singular) {
                         return call_user_func_array([$this, 'selectOne'], $args);
                     }
                     return call_user_func_array([$this, 'selectMany'], $args);
                 case 'set':
                     if ($singular) {
                         return call_user_func_array([$this, 'setOne'], $args);
                     }
                     return call_user_func_array([$this, 'setMany' . $suffix], $args);
                 case 'add':
                     if ($singular) {
                         return call_user_func_array([$this, 'addManyOne'], $args);
                     }
                     throw new Exception("Failed to add {$table}: No plural action available");
             }
         }
         if (strlen($method) > 5) {
             $token = substr($method, 0, 5);
             if (in_array($token, ['count'])) {
                 $name = substr($method, 5);
                 $plural = StringUtil::pluralize($name);
                 $singular = $plural !== $name;
                 $table = $this->getDatabase()->{$plural};
                 array_unshift($args, $table);
                 if ($singular) {
                     return call_user_func_array([$this, 'countOne'], $args);
                 }
                 return call_user_func_array([$this, 'countMany'], $args);
             }
         }
     }
     throw new BadMethodCallException("Failed to call method {$method}: Method doesnt exist");
 }
Beispiel #18
0
 public static function fromString($uriString)
 {
     return new static(StringUtil::map($uriString, ':', ['scheme', 'path']));
 }
Beispiel #19
0
 public function getModelClassName()
 {
     $nameSpaces = $this->_database->getModelNameSpaces();
     if (empty($nameSpaces)) {
         return null;
     }
     foreach ($nameSpaces as $nameSpace) {
         $className = rtrim($nameSpace, '\\') . '\\' . StringUtil::camelize(StringUtil::singularize($this->getName()));
         if (!class_exists($className)) {
             continue;
         }
         if (!is_subclass_of($className, 'Tale\\Data\\Row')) {
             throw new \Exception("Failed to use {$className} as a model class: " . "The class needs to extend Tale\\Data\\Row");
         }
         return $className;
     }
     return null;
 }