_registry->get( 'theme.loader' ); header( 'Content-Type: text/plain; charset=utf-8' ); $start = microtime( true ); foreach ( array( true, false ) as $for_admin ) { $twig = $loader->get_twig_instance( $for_admin, true ); $files = $this->get_files( $twig ); $this->compile( $twig, $files ); } echo 'Re-compiled in ' . ( microtime( true ) - $start ) . "\n"; exit( 0 ); } /** * Extract files locatable within provided Twig Environment. * * @param Twig_Environment $twig Instance to check. * * @return array Map of files => Twig templates. */ public function get_files( Twig_Environment $twig ) { $files = array(); try { $paths = $twig->getLoader()->getPaths(); foreach ( $paths as $path ) { $files += $this->read_files( $path, strlen( $path ) + 1 ); } } catch ( Exception $excpt ) { } return $files; } /** * Actually compile templates to cache directory. * * @param Twig_Environment $twig Instance to use for compilation. * @param array $file_list Map of files located previously. * * @return void */ public function compile( Twig_Environment $twig, array $file_list ) { foreach ( $file_list as $file => $template ) { $twig->loadTemplate( $template ); echo 'Compiled: ', $template, ' (', $file, ')', "\n"; } } /** * Read file system searching for twig files. * * @param string $path Directory to search in. * @param int $trim_length Number of characters to omit for templates. * * @return array Map of files => Twig templates. */ public function read_files( $path, $trim_length ) { $handle = opendir( $path ); $files = array(); if ( false === $handle ) { return $files; } while ( false !== ( $file = readdir( $handle ) ) ) { if ( '.' === $file{0} ) { continue; } $new_path = $path . DIRECTORY_SEPARATOR . $file; if ( is_dir( $new_path ) ) { $files += $this->read_files( $new_path, $trim_length ); } else if ( is_file( $new_path ) && '.twig' === strrchr( $new_path, '.' ) ) { $files[$new_path] = substr( $new_path, $trim_length ); } } closedir( $handle ); return $files; } /** * Adjust Twig environment for compilation. * * @param array $environment Initial environment arguments. * * @return */ public function ai1ec_twig_environment( array $environment ) { $environment['debug'] = false; $environment['cache'] = AI1EC_TWIG_CACHE_PATH; $environment['auto_reload'] = true; if ( ! $this->_check_dir( $environment['cache'] ) ) { throw new Ai1ec_Bootstrap_Exception( 'Failed to create cache directory: ' . $environment['cache'] ); } return $environment; } /** * Ensure cache directory pre-conditions. * * Before compilation starts cache directory must be empty but existing. * NOTE: it attempts to preserve `.gitignore` file in cache/ directory. * * @param string $cache_dir Directory to check. * * @return bool Validity. */ protected function _check_dir( $cache_dir ) { $parent = dirname( realpath( $cache_dir ) ); $gitignore = null; $gitfile = $parent . DIRECTORY_SEPARATOR . '.gitignore'; if ( is_file( $gitfile ) ) { $gitignore = file_get_contents( $gitfile ); } if ( ! $this->_prune_dir( $parent ) ) { return false; } if ( mkdir( $cache_dir, 0755, true ) ) { if ( null !== $gitignore ) { file_put_contents( $gitfile, $gitignore ); } return true; } return false; } /** * Remove directory and all it's contents. * * @param string $cache_dir Absolute path to remove. * * @return bool Success. */ protected function _prune_dir( $cache_dir ) { if ( ! file_exists( $cache_dir ) ) { return true; } $handle = opendir( $cache_dir ); if ( ! $handle ) { return false; } while ( false !== ( $file = readdir( $handle ) ) ) { if ( '.' === $file || '..' === $file ) { continue; } $path = $cache_dir . DIRECTORY_SEPARATOR . $file; if ( is_file( $path ) ) { if ( ! unlink( $path ) ) { return false; } } else { if ( ! $this->_prune_dir( $path ) ) { return false; } } } closedir( $handle ); return rmdir( $cache_dir ); } }