<?php use Tale\Util\ArrayUtil, Tale\Util\StringUtil, Tale\Util\PathUtil; include 'vendor/autoload.php'; $array = ['name' => 'someApp', 'path' => '/some/path', 'paths' => ['a' => '{{path}}/a', 'b' => '{{path}}/b'], 'feature' => ['path' => '{{paths.a}}/feature', 'name' => '{{name}}.Feature']]; var_dump($array); ArrayUtil::interpolate($array); var_dump($array); $singulars = ['user', 'user_group', 'user_group_field', 'user_group_status']; var_dump($singulars, array_map([StringUtil::class, 'pluralize'], $singulars), array_map([StringUtil::class, 'camelize'], $singulars), array_map([StringUtil::class, 'variablize'], $singulars), array_map([StringUtil::class, 'canonicalize'], $singulars)); foreach (range(0, 10) as $i) { list($pl, $pr, $sl, $sr) = array_map(function () { return mt_rand(0, 1) ? '/' : ''; }, array_fill(0, 4, null)); $parentPath = $pl . 'parent/path' . $pr; $subPath = $sl . 'sub/path' . $sr; var_dump($parentPath, $subPath, PathUtil::join($parentPath, $subPath)); }
public function mergeOptionFile($path, $recursive = false, $reverse = false) { $this->mergeOptions(ArrayUtil::fromFile($path), $recursive, $reverse); return $this; }
public function run(App $previousApp = null) { //Make sure all correct feature aliases are registered $this->_registerFeatureAliases(); //We will sort the features by dependency on other features //and initialize them in the correct order //First we create an instance of all features. /** * @var \Tale\App\FeatureBase[] $features */ $features = []; foreach ($this->getOption('features') as $name => $options) { //Aliases are resolved. $className = $this->_featureFactory->resolveClassName($name); //We don't want duplicate instances. Rather create a new feature //It's better for unique identification if (isset($features[$className])) { throw new RuntimeException("Failed to add feature {$name}({$className}): Feature does already exist"); } //This creates the actual instance via Tale\Factory $feature = $this->_featureFactory->createInstance($className, [$this]); //We can pass a string as the options to use a config file if (is_string($options)) { $feature->appendOptionFile($options, true); } else { if (is_array($options)) { $feature->appendOptions($options, true); } else { throw new RuntimeException("Failed to initialize feature {$name}({$className}): " . "Config needs to be a path to a file or an option array"); } } $features[] = $feature; } //All features are instanced and got all the options they will get //at this point. //Now we sort the features by dependencies. //TODO: Circular dependencies probably f**k up. ArrayUtil::mergeSort($features, [__CLASS__, 'compareFeatures']); $classes = array_map('get_class', $features); $features = array_combine($classes, $features); //Now we can initialize the features //Since our deps are ordered now, we can just iterate foreach ($features as $feature) { //First append our dependencies foreach ($feature->getDependencies() as $name => $className) { if (isset($features[$className])) { $feature->setDependency($name, $features[$className]); } } //Now initialize the feature //This is the possibility to add events etc. $feature->init(); } //This is only sorting! We dont ensure, that the feature exists. //The feature has to do that by itself (through an easy way, look at it) //Put together our event args $args = ['app' => $this, 'previousApp' => $previousApp]; //First, we prepare (and let features prepare) if ($this->emit('beforeRun', new Event\Args($args))) { $this->_setPhpOptions(); //Then we run if ($this->emit('run', new Event\Args($args))) { //Clear our features $this->_features = null; //Allow clean-up at the end (Notice that the "true" //makes it reverse $this->emit('afterRun', new Event\Args($args), true); } } return $this; }
/** * Loads a collection from a given file name * * json => json_decode * php => include * yml? => Tale\Yaml\Parser * xml => Tale\Dom\Xml\Parser * * @param string $path The path of the collection file to load * * @return static The config object generated from the passed file */ public static function fromFile($path) { return new static(ArrayUtil::fromFile($path)); }
/** * 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 = ArrayUtil::resolve($source, $m[1], $defaultValue, $delimeter); if ($resolved === null) { return $m[0]; } return $resolved; }, $string); }