/** * {@inheritdoc} * * @param Isolator $isolator Custom PHP isolator instance. */ public function process($source, Isolator $isolator = null) { $isolator = !empty($isolator) ? $isolator : new Isolator(); //Real php source code isolation $source = $isolator->isolatePHP($source); //Restoring only evaluator blocks $phpBlocks = $evaluateBlocks = []; foreach ($isolator->getBlocks() as $id => $phpBlock) { foreach ($this->options['flags'] as $flag) { if (strpos($phpBlock, $flag) !== false) { $evaluateBlocks[$id] = $phpBlock; continue 2; } } $phpBlocks[$id] = $phpBlock; } $source = $isolator->setBlocks($evaluateBlocks)->repairPHP($source); $isolator->setBlocks($phpBlocks); //Required to prevent collisions $filename = $this->views->config()['cache']['directory'] . "/{$this->uniqueID()}.php"; try { $this->files->write($filename, $source, FilesInterface::RUNTIME, true); ob_start(); include_once $filename; $source = ob_get_clean(); $this->files->delete($filename); } catch (\ErrorException $exception) { throw $exception; } return $isolator->repairPHP($source); }
/** * {@inheritdoc} */ public function getTimestamp($key) { if ($this->files->exists($key)) { return $this->files->time($key); } return 0; }
/** * {@inheritdoc} */ public function open($filename) { if (!$this->files->exists($filename)) { throw new ImporterException("Unable import translator bundles from '{$filename}', file does not exists."); } $this->parseStrings($this->files->read($filename)); return $this; }
/** * {@inheritdoc} */ public function fileReflection($filename) { $fileMD5 = $this->files->md5($filename = $this->files->normalizePath($filename)); $reflection = new ReflectionFile($this->fetchTokens($filename), (array) $this->memory->loadData($fileMD5, self::MEMORY_LOCATION)); //Let's save to cache $this->memory->saveData($fileMD5, $reflection->exportSchema(), static::MEMORY_LOCATION); return $reflection; }
/** * Handle log message. * * @param int $level Log message level. * @param string $message Message. * @param array $context Context data. */ public function __invoke($level, $message, array $context = []) { $message = \Spiral\interpolate($this->options['format'], ['date' => date($this->options['dateFormat'], time()), 'level' => $level, 'message' => $message]); if ($this->files->append($this->options['filename'], "{$message}\n", $this->options['mode'], true)) { if ($this->files->size($this->options['filename']) > $this->options['filesize']) { $this->files->move($this->options['filename'], $this->options['filename'] . $this->options['rotatePostfix']); } } }
/** * Export UML classes diagram to specified file, all found Documents with their fields, methods * and compositions will be used to generate such UML. * * @param string $filename * @return bool */ public function export($filename) { $this->line('@startuml'); foreach ($this->builder->getDocuments() as $document) { $this->renderDocument($document); } $this->line('@enduml'); return $this->files->write($filename, join("\n", $this->lines)); }
/** * @param DirectoriesInterface $directories * @param FilesInterface $files * @param EncrypterConfig $config */ public function perform(DirectoriesInterface $directories, FilesInterface $files, EncrypterConfig $config) { $envFilename = $directories->directory('root') . '.env'; if (!$files->exists($envFilename)) { $this->writeln("<fg=red>'env.' file does not exists, unable to sek encryption key.</fg=red>"); } $files->write($envFilename, str_replace($config->getKey(), Strings::random(32), $files->read($envFilename))); $this->writeln("<info>Encryption key has been successfully updated.</info>"); }
/** * Last update time. * * @param string $key * @return int */ public function getTimestamp($key) { if (!$this->environment->cachable()) { //Always expired return 0; } if ($this->files->exists($key)) { return $this->files->time($key); } return 0; }
/** * Index directory files to locate function calls related to Translator or TranslatorTrait * methods. * * @param string $directory * @param array $excludes Filename words to be excluded from analysis. * @return self * @throws TokenizerException * @throws ReflectionException * @throws TranslatorException */ public function indexDirectory($directory = null, array $excludes = []) { foreach ($this->files->getFiles($directory, 'php') as $filename) { foreach ($excludes as $exclude) { if (strpos($filename, $exclude) !== false) { continue 2; } } $this->indexCalls($this->tokenizer->fileReflection($filename)->getCalls()); } return $this; }
/** * List of core directories with normalized paths, longest directories first. * * @return array */ private function getDirectories() { $directories = $this->core->getDirectories(); foreach ($directories as &$directory) { $directory = $this->files->normalizePath($directory); unset($directory); } //Sorting to get longest first uasort($directories, function ($valueA, $valueB) { return strlen($valueA) < strlen($valueB); }); return $directories; }
/** * Check if given locale exists. * * @param string $locale * @return bool */ private function hasLocale($locale) { if (array_key_exists($locale, $this->loadedLocales)) { return true; } return $this->source->hasLocale($locale); }
/** * @param FilesInterface $files * @param DirectoriesInterface $directories */ public function perform(FilesInterface $files, DirectoriesInterface $directories) { $cacheDirectory = $directories->directory('cache'); if (!$files->exists($cacheDirectory)) { $this->writeln("Cache directory is missing, no cache to be cleaned."); return; } $this->isVerbosity() && $this->writeln("<info>Cleaning application runtime cache:</info>"); foreach ($files->getFiles($cacheDirectory) as $filename) { $files->delete($filename); if ($this->isVerbosity()) { $this->writeln($files->relativePath($filename, $cacheDirectory)); } } $this->writeln("<info>Runtime cache has been cleared.</info>"); }
/** * Detect compiler by view path (automatically resolved based on extension). * * @todo cache needed? * @param string $path * @return string */ protected function detectEngine($path) { if (isset($this->associationCache[$path])) { return $this->associationCache[$path]; } //File extension can help us to detect engine faster (attention, does not work with complex //extensions at this moment). $extension = $this->files->extension($path); $detected = null; foreach ($this->config->getEngines() as $engine) { if (!empty($extension) && $extension == $this->config->engineExtension($engine)) { //Found by extension $detected = $engine; break; } //Trying automatic (no extension) detection $loader = $this->loader($engine); try { if (!empty($loader->viewName($path))) { $detected = $engine; } } catch (LoaderException $exception) { //Does not related to such engine } } if (empty($detected)) { throw new ViewsException("Unable to detect view engine for '{$path}'."); } return $this->associationCache[$path] = $detected; }
/** * {@inheritdoc} */ public function report() { $this->debugger->logger()->error($this->getMessage()); if (!$this->config['reporting']['enabled']) { //No need to record anything return; } //Snapshot filename $filename = \Spiral\interpolate($this->config['reporting']['filename'], ['date' => date($this->config['reporting']['dateFormat'], time()), 'exception' => $this->getName()]); //Writing to hard drive $this->files->write($this->config['reporting']['directory'] . '/' . $filename, $this->render(), FilesInterface::RUNTIME, true); $snapshots = $this->files->getFiles($this->config['reporting']['directory']); if (count($snapshots) > $this->config['reporting']['maxSnapshots']) { $oldestSnapshot = ''; $oldestTimestamp = PHP_INT_MAX; foreach ($snapshots as $snapshot) { $snapshotTimestamp = $this->files->time($snapshot); if ($snapshotTimestamp < $oldestTimestamp) { $oldestTimestamp = $snapshotTimestamp; $oldestSnapshot = $snapshot; } } $this->files->delete($oldestSnapshot); } }
/** * {@inheritdoc} * * @param Isolator|null $isolator */ public function process($source, $namespace, $view, $cachedFilename = null, Isolator $isolator = null) { $isolator = !empty($isolator) ? $isolator : new Isolator(); //Let's hide original php blocks $source = $isolator->isolatePHP($source); //Now we have to detect blocks which has to be compiled //Restoring only evaluator blocks $phpBlocks = $evaluateBlocks = []; foreach ($isolator->getBlocks() as $id => $phpBlock) { if ($this->evaluatable($phpBlock)) { $evaluateBlocks[$id] = $phpBlock; continue; } $phpBlocks[$id] = $phpBlock; } //Let's only mount blocks to be evaluated $source = $isolator->setBlocks($evaluateBlocks)->repairPHP($source); $isolator->setBlocks($phpBlocks); //Let's create temporary filename $filename = $this->evalFilename($cachedFilename); //I must validate file syntax in a future try { $this->files->write($filename, $source, FilesInterface::RUNTIME, true); ob_start(); $__outputLevel__ = ob_get_level(); //Can be accessed in evaluated php $this->namespace = $namespace; $this->view = $view; try { include_once $this->files->localUri($filename); } finally { while (ob_get_level() > $__outputLevel__) { ob_end_clean(); } } $this->namespace = ''; $this->view = ''; $source = ob_get_clean(); //Dropping temporary filename $this->files->delete($filename); } catch (\ErrorException $exception) { throw $exception; } //Restoring original php blocks return $isolator->repairPHP($source); }
/** * {@inheritdoc} */ public function flush() { $files = $this->files->getFiles($this->options['directory'], $this->options['extension']); foreach ($files as $filename) { $this->files->delete($filename); } return count($files); }
/** * @param string $config * @return string * @throws RegistratorException */ protected function configFilename($config) { $filename = $this->directories->directory('config') . $config . Configurator::EXTENSION; if (!$this->files->exists($filename)) { throw new RegistratorException("Unable to find filename for config '{$config}'."); } return $filename; }
/** * {@inheritdoc} */ public function getSize() { $totalSize = 0; foreach ($this->files->getFiles($this->getLocation()) as $filename) { $totalSize += filesize($filename); } return $totalSize; }
/** * Load environment data. * * @return $this */ public function load() { if (!$this->files->exists($this->filename)) { throw new EnvironmentException("Unable to load environment, file is missing"); } //Unique env file hash $this->id = $this->files->md5($this->filename); if (!empty($values = $this->memory->loadData($this->id, static::MEMORY_SECTION))) { //Restore from cache $this->initEnvironment($values); return $this; } //Load env values using DotEnv extension $values = $this->initEnvironment($this->parseValues($this->filename)); $this->memory->saveData($this->id, $values, static::MEMORY_SECTION); return $this; }
/** * Cast local filename to be used in file based methods and etc. * * @param string|StreamInterface $source * @return string */ protected function castFilename($source) { if (empty($source) || is_string($source)) { if (!$this->files->exists($source)) { //This code is going to use additional abstraction layer to connect storage and guzzle return StreamWrapper::getUri(\GuzzleHttp\Psr7\stream_for('')); } return $source; } if ($source instanceof UploadedFileInterface || $source instanceof StreamableInterface) { $source = $source->getStream(); } if ($source instanceof StreamInterface) { return StreamWrapper::getUri($source); } throw new ServerException("Unable to get filename for non Stream instance."); }
/** * @param ViewsConfig $config * @param FilesInterface $files */ public function perform(ViewsConfig $config, FilesInterface $files) { if (!$files->exists($config->cacheDirectory())) { $this->writeln("Cache directory is missing, no cache to be cleaned."); return; } $this->isVerbosity() && $this->writeln("<info>Clearing view cache:</info>"); $cachedViews = $files->getFiles($config->cacheDirectory()); foreach ($cachedViews as $filename) { $files->delete($filename); if ($this->isVerbosity()) { $this->writeln($files->relativePath($filename, $config->cacheDirectory())); } } if (empty($filename) && $this->isVerbosity()) { $this->writeln("No cached views were found."); } $this->writeln("<info>View cache has been cleared.</info>"); }
/** * Clean old snapshots. * * @todo Possibly need better implementation. * @param array $snapshots */ protected function performRotation(array $snapshots) { $oldest = ''; $oldestTimestamp = PHP_INT_MAX; foreach ($snapshots as $snapshot) { $snapshotTimestamp = $this->files->time($snapshot); if ($snapshotTimestamp < $oldestTimestamp) { $oldestTimestamp = $snapshotTimestamp; $oldest = $snapshot; } } $this->files->delete($oldest); }
/** * Internal method to fetch filename using multiple input formats. * * @param mixed|UploadedFileInterface $filename * @param bool $onlyUploaded Check if file uploaded. * @return string|bool */ protected function filename($filename, $onlyUploaded = true) { if (empty($filename) || $onlyUploaded && !$this->isUploaded($filename)) { return false; } if ($filename instanceof UploadedFileInterface || $filename instanceof StreamableInterface) { return StreamWrapper::getUri($filename->getStream()); } if (is_array($filename)) { $filename = $filename['tmp_name']; } return $this->files->exists($filename) ? $filename : false; }
/** * Create stream for given filename. * * @param string|StreamInterface|StreamableInterface $filename * @return StreamInterface */ private function getStream($filename) { if ($filename instanceof StreamableInterface) { return $filename->getStream(); } if ($filename instanceof StreamInterface) { return $filename; } if (is_resource($filename)) { return new Stream($filename, 'r'); } if (!$this->files->isFile($filename)) { throw new \InvalidArgumentException("Unable to allocate response body stream, file does not exist."); } return new Stream(fopen($this->files->localUri($filename), 'r')); }
/** * Load all bundle strings from specified language. * * @param string $language * @param string $prefix Only bundle names started with this prefix will be exported. * @return array */ private function loadBundles($language, $prefix = '') { $bundles = $this->files->getFiles($this->translator->config()['languages'][$language]['directory']); $result = []; foreach ($bundles as $filename) { $bundle = substr(basename($filename), 0, -1 * strlen($this->files->extension($filename))); if (!empty($prefix) && stripos($bundle, $prefix) !== 0) { continue; } try { $result[$bundle] = (include $filename); } catch (\Exception $exception) { } } return $result; }
/** * Cast stream associated with origin data. * * @param string|StreamInterface $source * @return StreamInterface */ protected function castStream($source) { if ($source instanceof UploadedFileInterface || $source instanceof StreamableInterface) { $source = $source->getStream(); } if ($source instanceof StreamInterface) { return $source; } if (empty($source)) { //This code is going to use additional abstraction layer to connect storage and guzzle return \GuzzleHttp\Psr7\stream_for(''); } if (is_string($source) && $this->files->exists($source)) { $source = fopen($source, 'rb'); } return \GuzzleHttp\Psr7\stream_for($source); }
/** * Find view file specified by namespace and view name and associated engine id. * * @param string $namespace * @param string $view * @param string $engine Found engine id, reference. * @return string * @throws ViewException */ public function getFilename($namespace, $view, &$engine = null) { if (!isset($this->namespaces[$namespace])) { throw new ViewException("Undefined view namespace '{$namespace}'."); } //This part better be cached one dat foreach ($this->namespaces[$namespace] as $directory) { foreach ($this->config['engines'] as $engine => $options) { foreach ($options['extensions'] as $extension) { $candidate = $directory . FilesInterface::SEPARATOR . $view . '.' . $extension; if ($this->files->exists($candidate)) { return $this->files->normalizePath($candidate); } } } } throw new ViewException("Unable to find view '{$view}' in namespace '{$namespace}'."); }
/** * Locate view filename based on current loader settings. * * @param string $path * @return string * @throws LoaderException */ protected function findView($path) { if (isset($this->cache[$path])) { return $this->cache[$path][0]; } $this->validateName($path); list($namespace, $filename) = $this->parsePath($path); if (!isset($this->namespaces[$namespace])) { throw new LoaderException("Undefined view namespace '{$namespace}'."); } foreach ($this->namespaces[$namespace] as $directory) { if ($this->files->exists($directory . $filename)) { $this->cache[$path] = [$directory . $filename, $namespace, $this->resolveName($filename)]; return $this->cache[$path][0]; } } throw new LoaderException("Unable to locate view '{$filename}' in namespace '{$namespace}'."); }
/** * Get all memory sections belongs to given memory location (default location to be used if * none specified). * * @param string $location * @return array */ public function getSections($location = null) { if (!empty($location)) { $location = $this->directory . $location . '/'; } else { $location = $this->directory; } if (!$this->files->exists($location)) { return []; } $finder = new Finder(); $finder->in($location); /** * @var SplFileInfo $file */ $sections = []; foreach ($finder->name("*" . static::EXTENSION) as $file) { $sections[] = substr($file->getRelativePathname(), 0, -1 * strlen(static::EXTENSION)); } return $sections; }
/** * @param DirectoriesInterface $directories * @param FilesInterface $files */ protected function ensurePermissions(DirectoriesInterface $directories, FilesInterface $files) { $this->writeln("<info>Verifying runtime directory existence and file permissions...</info>"); $runtime = $directories->directory('runtime'); if (!$files->exists(directory('runtime'))) { $files->ensureDirectory(directory('runtime')); $this->writeln("Runtime data directory was created."); return; } foreach ($files->getFiles(directory('runtime')) as $filename) { //Both file and it's directory must be writable $files->setPermissions($filename, FilesInterface::RUNTIME); $files->setPermissions(dirname($filename), FilesInterface::RUNTIME); } $this->writeln("Runtime directory permissions were updated."); }