function css($file, $media = null)
 {
     /* If file is CSS, check if there is a LESS file */
     if (preg_match('/\\.css$/i', $file)) {
         $less = preg_replace('/\\.css$/i', '.less', $file);
         if (is_file(Director::getAbsFile($less))) {
             $file = $less;
         }
     }
     /* If less file, then check/compile it */
     if (preg_match('/\\.less$/i', $file)) {
         $compiler = 'checkedCompile';
         $out = preg_replace('/\\.less$/i', '.css', $file);
         /* Force recompile if ?flush */
         if (isset($_GET['flush'])) {
             $compiler = 'compileFile';
         }
         /* Create instance */
         $less = new lessc();
         /* Automatically compress if in live mode */
         if (DIRECTOR::isLive()) {
             $less->setFormatter("compressed");
         }
         try {
             $less->{$compiler}(Director::getAbsFile($file), Director::getAbsFile($out));
         } catch (Exception $ex) {
             trigger_error("lessphp fatal error: " . $ex->getMessage(), E_USER_ERROR);
         }
         $file = $out;
     }
     /* Return css path */
     return parent::css($file, $media);
 }
 public function combine_files($combinedFileName, $files, $media = null)
 {
     foreach ($files as $i => $fileName) {
         $files[$i] = $this->collectFile($fileName);
     }
     return parent::combine_files($combinedFileName, $files, $media);
 }
 protected function path_for_file($fileOrUrl)
 {
     if (preg_match('{^//|http[s]?}', $fileOrUrl)) {
         return $fileOrUrl;
     } else {
         if (!Director::fileExists($fileOrUrl)) {
             $fileOrUrl = MODULES_DIR . '/' . $fileOrUrl;
         }
         return parent::path_for_file($fileOrUrl);
     }
 }
 /**
  * Default includeInHTML strips out CSS if the file doesn't exist. We need to add it back in if it's a redirected rewrite
  * @see sapphire/core/Requirements_Backend#includeInHTML($templateFile, $content)
  */
 function includeInHTML($templateFile, $content)
 {
     $content = parent::includeInHTML($templateFile, $content);
     $requirements = '';
     foreach (array_diff_key($this->css, $this->blocked) as $file => $params) {
         $path = self::path_for_file($file);
         if (!$path && ($path = self::path_for_file('assets/' . basename($file)))) {
             $media = isset($params['media']) && !empty($params['media']) ? " media=\"{$params['media']}\"" : "";
             $requirements .= "<link rel=\"stylesheet\" type=\"text/css\"{$media} href=\"{$file}\" />\n";
         }
     }
     return preg_replace("/(<\\/head[^>]*>)/i", $requirements . "\\1", $content);
 }
示例#5
0
 function css($file, $media = null)
 {
     /**
      * Only initiate automatically if:
      * - webiste is in dev mode
      * - or a ?flush is called
      */
     if (preg_match('/\\.less$/i', $file) || Director::isDev() || isset($_GET['flush'])) {
         /* If file is CSS, check if there is a LESS file */
         if (preg_match('/\\.css$/i', $file)) {
             $less = preg_replace('/\\.css$/i', '.less', $file);
             if (is_file(Director::getAbsFile($less))) {
                 $file = $less;
             }
         }
         /* If less file exists, then check/compile it */
         if (preg_match('/\\.less$/i', $file)) {
             $out = preg_replace('/\\.less$/i', '.css', $file);
             $css_file = Director::getAbsFile($out);
             $options = array();
             /* Automatically compress if in live mode */
             if (Director::isLive()) {
                 $options['compress'] = true;
             }
             try {
                 /* Force recompile & only write to css if updated */
                 if (isset($_GET['flush']) || !Director::isLive()) {
                     /* Create instance */
                     $parser = new Less_Parser($options);
                     if (!empty(self::$variables)) {
                         $parser->ModifyVars(self::$variables);
                     }
                     /* calculate the LESS file's parent URL */
                     $css_dir = rtrim(Director::baseURL(), '/') . Director::makeRelative(dirname(Director::getAbsFile($file)) . '/');
                     $parser->parseFile(Director::getAbsFile($file), $css_dir);
                     $css = $parser->getCss();
                     if (!is_file($css_file) || md5_file($css_file) != md5($css)) {
                         file_put_contents($css_file, $css);
                     }
                 }
             } catch (Exception $ex) {
                 trigger_error("Less.php fatal error: " . $ex->getMessage(), E_USER_ERROR);
             }
             $file = $out;
         }
     }
     /* Return css path */
     return parent::css($file, $media);
 }
 /**
  * Finds the path for specified file
  *
  * @param string $fileOrUrl
  * @return string|bool
  */
 protected function path_for_file($fileOrUrl)
 {
     // only handle files in themes folder
     if (!Controller::has_curr() || is_a(Controller::curr(), 'LeftAndMain')) {
         return parent::path_for_file($fileOrUrl);
     } else {
         if (preg_match('{^//|http[s]?}', $fileOrUrl)) {
             return $fileOrUrl;
         } elseif (Director::fileExists($fileOrUrl)) {
             $filePath = preg_replace('/\\?.*/', '', Director::baseFolder() . '/' . $fileOrUrl);
             $baseurl = Director::baseURL();
             // url parameters
             if (strpos($fileOrUrl, '?') !== false) {
                 $parameters = '?' . substr($fileOrUrl, strpos($fileOrUrl, '?') + 1);
                 $fileOrUrl = substr($fileOrUrl, 0, strpos($fileOrUrl, '?'));
             } else {
                 $parameters = '';
             }
             // get base path
             $baseFolder = Director::baseFolder();
             // get combined files folder
             $combinedFilesFolder = rtrim($this->getCombinedFilesFolder(), '/');
             if (!file_exists($baseFolder . '/' . $combinedFilesFolder)) {
                 Filesystem::makeFolder($baseFolder . '/' . $combinedFilesFolder);
             }
             // get file name
             $fileName = substr($filePath, strrpos($filePath, '/') + 1);
             // get prefix
             $prefix = filemtime($filePath) . '-';
             $prefixedFilePath = $baseFolder . '/' . $combinedFilesFolder . '/' . $prefix . $fileName;
             // clean up and create file
             if (!file_exists($prefixedFilePath)) {
                 // remove old prefixed files
                 foreach (glob($baseFolder . '/' . $combinedFilesFolder . '/' . '[0-9]*-' . $fileName) as $file) {
                     unlink($file);
                 }
                 // copy standard file to prefixed file
                 copy($filePath, $prefixedFilePath);
             }
             return "{$baseurl}{$combinedFilesFolder}/{$prefix}{$fileName}{$parameters}";
         } else {
             return false;
         }
     }
 }
 protected function path_for_file($fileOrUrl)
 {
     //		Debug::message($fileOrUrl . " " . (Controller::curr()->IsCMS() ? "Admin" : "FrontEnd"));
     return parent::path_for_file($fileOrUrl);
 }
 function testRequirementsBackend()
 {
     $backend = new Requirements_Backend();
     $backend->javascript(SAPPHIRE_DIR . '/tests/forms/a.js');
     $this->assertTrue(count($backend->get_javascript()) == 1, "There should be only 1 file included in required javascript.");
     $this->assertTrue(in_array(SAPPHIRE_DIR . '/tests/forms/a.js', $backend->get_javascript()), "/test/forms/a.js should be included in required javascript.");
     $backend->javascript(SAPPHIRE_DIR . '/tests/forms/b.js');
     $this->assertTrue(count($backend->get_javascript()) == 2, "There should be 2 files included in required javascript.");
     $backend->block(SAPPHIRE_DIR . '/tests/forms/a.js');
     $this->assertTrue(count($backend->get_javascript()) == 1, "There should be only 1 file included in required javascript.");
     $this->assertFalse(in_array(SAPPHIRE_DIR . '/tests/forms/a.js', $backend->get_javascript()), "/test/forms/a.js should not be included in required javascript after it has been blocked.");
     $this->assertTrue(in_array(SAPPHIRE_DIR . '/tests/forms/b.js', $backend->get_javascript()), "/test/forms/b.js should be included in required javascript.");
     $backend->css(SAPPHIRE_DIR . '/tests/forms/a.css');
     $this->assertTrue(count($backend->get_css()) == 1, "There should be only 1 file included in required css.");
     $this->assertArrayHasKey(SAPPHIRE_DIR . '/tests/forms/a.css', $backend->get_css(), "/tests/forms/a.css should be in required css.");
     $backend->block(SAPPHIRE_DIR . '/tests/forms/a.css');
     $this->assertTrue(count($backend->get_css()) == 0, "There should be nothing in required css after file has been blocked.");
 }
 public function testProcessOnlyIncludesRequirementsOnce()
 {
     $template = new SSViewer(array('SSViewerTestProcess'));
     $basePath = dirname($this->getCurrentRelativePath()) . '/forms';
     $backend = new Requirements_Backend();
     $backend->set_combined_files_enabled(false);
     $backend->combine_files('RequirementsTest_ab.css', array($basePath . '/RequirementsTest_a.css', $basePath . '/RequirementsTest_b.css'));
     Requirements::set_backend($backend);
     $this->assertEquals(1, substr_count($template->process(array()), "a.css"));
     $this->assertEquals(1, substr_count($template->process(array()), "b.css"));
     // if we disable the requirements then we should get nothing
     $template->includeRequirements(false);
     $this->assertEquals(0, substr_count($template->process(array()), "a.css"));
     $this->assertEquals(0, substr_count($template->process(array()), "b.css"));
 }
 public function include_in_response(\SS_HTTPResponse $response)
 {
     if ($this->Eventful()) {
         $this->Eventful()->fire('assets:beforeProcessResponse', $response);
     }
     $this->assets();
     parent::include_in_response($response);
     if (Director::is_ajax()) {
         $this->_response = $response;
     }
     $this->attachCustomScriptsToResponse();
     if ($this->Eventful()) {
         $this->Eventful()->fire('assets:afterProcessResponse', $response);
     }
 }
示例#11
0
 public function testSuffix()
 {
     $template = '<html><head></head><body><header>My header</header><p>Body</p></body></html>';
     $basePath = $this->getCurrentRelativePath();
     $basePath = 'framework' . substr($basePath, strlen(FRAMEWORK_DIR));
     $backend = new Requirements_Backend();
     $backend->javascript($basePath . '/RequirementsTest_a.js');
     $backend->javascript($basePath . '/RequirementsTest_b.js?foo=bar&bla=blubb');
     $backend->css($basePath . '/RequirementsTest_a.css');
     $backend->css($basePath . '/RequirementsTest_b.css?foo=bar&bla=blubb');
     $backend->set_suffix_requirements(true);
     $html = $backend->includeInHTML(false, $template);
     $this->assertRegexp('/RequirementsTest_a\\.js\\?m=[\\d]*"/', $html);
     $this->assertRegexp('/RequirementsTest_b\\.js\\?m=[\\d]*&amp;foo=bar&amp;bla=blubb"/', $html);
     $this->assertRegexp('/RequirementsTest_a\\.css\\?m=[\\d]*"/', $html);
     $this->assertRegexp('/RequirementsTest_b\\.css\\?m=[\\d]*&amp;foo=bar&amp;bla=blubb"/', $html);
     $backend->set_suffix_requirements(false);
     $html = $backend->includeInHTML(false, $template);
     $this->assertNotContains('RequirementsTest_a.js=', $html);
     $this->assertNotRegexp('/RequirementsTest_a\\.js\\?m=[\\d]*"/', $html);
     $this->assertNotRegexp('/RequirementsTest_b\\.js\\?m=[\\d]*&amp;foo=bar&amp;bla=blubb"/', $html);
     $this->assertNotRegexp('/RequirementsTest_a\\.css\\?m=[\\d]*"/', $html);
     $this->assertNotRegexp('/RequirementsTest_b\\.css\\?m=[\\d]*&amp;foo=bar&amp;bla=blubb"/', $html);
 }
 function css($file, $media = null)
 {
     /* Only initiate if webiste is in dev mode or a ?flush is called */
     if (preg_match('/\\.less$/i', $file) || Director::isDev() || isset($_GET['flush'])) {
         /* If file is CSS, check if there is a LESS file */
         if (preg_match('/\\.css$/i', $file)) {
             $less = preg_replace('/\\.css$/i', '.less', $file);
             if (is_file(Director::getAbsFile($less))) {
                 $file = $less;
             }
         }
         /* If less file exists, then check/compile it */
         if (preg_match('/\\.less$/i', $file)) {
             $out = preg_replace('/\\.less$/i', '.css', $file);
             $css_file = Director::getAbsFile($out);
             $options = array();
             /* Automatically compress if in live mode */
             if (Director::isLive()) {
                 $options['compress'] = true;
             }
             try {
                 /* Force recompile & only write to css if updated */
                 if (isset($_GET['flush']) || !Director::isLive()) {
                     /* Force deleting of all cache files on flush */
                     if (file_exists(self::$cacheDir) && isset($_GET['flush']) && !self::$already_flushed) {
                         $paths = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(self::$cacheDir, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST);
                         foreach ($paths as $path) {
                             $path->isDir() && !$path->isLink() ? rmdir($path->getPathname()) : unlink($path->getPathname());
                         }
                         /* make sure we only flush once per request and not for each *.less */
                         self::$already_flushed = true;
                     }
                     /* Set cache directory */
                     $options['cache_dir'] = self::$cacheDir;
                     /* Set cache method */
                     $options['cache_method'] = self::$cacheMethod;
                     /* Calculate the LESS file's parent URL */
                     $css_dir = dirname(Director::baseURL() . $file) . '/';
                     /* Generate and return cached file path */
                     $cached_file = self::$cacheDir . '/' . Less_Cache::Get(array(Director::getAbsFile($file) => $css_dir), $options, self::$variables);
                     /* check cache vs. css and overwrite if necessary */
                     if (!is_file($css_file) || md5_file($css_file) != md5_file($cached_file)) {
                         copy($cached_file, $css_file);
                     }
                 }
             } catch (Exception $ex) {
                 trigger_error('Less.php fatal error: ' . $ex->getMessage(), E_USER_ERROR);
             }
             $file = $out;
         }
     }
     /* Return css file path */
     return parent::css($file, $media);
 }
 /**
  * Update the given HTML content with the appropriate include tags for the registered
  * requirements. Needs to receive a valid HTML/XHTML template in the $content parameter,
  * including a <head> tag. The requirements will insert before the closing <head> tag automatically.
  *
  * @todo Calculate $prefix properly
  *
  * @param string $templateFilePath Absolute path for the *.ss template file
  * @param string $content HTML content that has already been parsed from the $templateFilePath through {@link SSViewer}.
  * @return string HTML content thats augumented with the requirements before the closing <head> tag.
  */
 function includeInHTML($templateFile, $content)
 {
     if ($this->isBackendController()) {
         //currently, it's not loading tinymce otherwise
         return parent::includeInHTML($templateFile, $content);
     }
     $hasHead = strpos($content, '</head>') !== false || strpos($content, '</head ') !== false;
     $hasRequirements = $this->css || $this->javascript || $this->customCSS || $this->customScript || $this->customHeadTags;
     if (!$hasHead || !$hasRequirements) {
         return $content;
     }
     $script_template = "<script type=\"text/javascript\">\n//<![CDATA[\n" . "%s" . "\n//]]>\n</script>\n";
     $ready_template = "head.ready(function() {\n" . "%s" . "\n});\n";
     $readyRequirements = $cleanRequirements = '';
     // Include HeadJS, the only script in your head
     $headerRequirements = "<script type=\"text/javascript\" src=\"" . self::getHeadJsUrl() . "\"></script>\n";
     // Combine files - updates $this->javascript and $this->css
     $this->process_combined_files();
     $named_files = self::getNamedFiles();
     // add the css requirements, even allow a callback
     $cssFiles = array_diff_key($this->css, $this->blocked);
     if (!empty($cssFiles)) {
         foreach ($cssFiles as $file => $params) {
             $name = str_replace('-', '', basename($file, '.css'));
             $path = Convert::raw2xml($this->path_for_file($file));
             if ($path) {
                 if (isset($params['media']) && !empty($params['media'])) {
                     $headerRequirements .= "<link rel=\"stylesheet\" type=\"text/css\" media=\"{$params['media']}\" href=\"{$path}\" />\n";
                 } else {
                     $path = str_replace('&amp;', '&', $path);
                     if ($named_files) {
                         $path = $name . '":"' . $path;
                     }
                     $callback = $this->get_callback($file) ? ", function(){" . $this->get_callback($file) . "}" : "";
                     $readyRequirements .= "head.load(\"" . $path . "\"{$callback});\n";
                 }
             }
         }
     }
     $jsFiles = array_diff_key($this->javascript, $this->blocked);
     if (!empty($jsFiles)) {
         foreach ($jsFiles as $file => $dummy) {
             $name = str_replace('-', '', basename($file, '.js'));
             $path = Convert::raw2xml($this->path_for_file($file));
             $path = str_replace('&amp;', '&', $path);
             if ($path) {
                 if ($named_files) {
                     $path = $name . '":"' . $path;
                 }
                 $callback = $this->get_callback($file) ? ", function(){" . $this->get_callback($file) . "}" : "";
                 $readyRequirements .= "head.load(\"" . $path . "\"{$callback});\n";
             }
         }
     }
     // @todo: store all css files in arrays with media param as the key, then do a headjs test for each mediaparam
     // store all "custom" css in the header, because this may have critical styling to fix FOUC issues
     $customCSS = array_diff_key($this->customCSS, $this->blocked);
     if (!empty($customCSS)) {
         foreach ($customCSS as $css) {
             $headerRequirements .= "<style type=\"text/css\">\n{$css}\n</style>\n";
         }
     }
     // add all inline javascript *after* including external files which
     // they might rely on
     $customJS = array_diff_key($this->customScript, $this->blocked);
     if (!empty($customJS)) {
         foreach ($customJS as $script) {
             if (in_array($script, self::$do_not_wrap)) {
                 $cleanRequirements .= $script;
             } else {
                 $readyRequirements .= $script;
             }
         }
     }
     foreach (array_diff_key($this->customHeadTags, $this->blocked) as $customHeadTag) {
         $headerRequirements .= "{$customHeadTag}\n";
     }
     // put the core js just before the </head>
     $content = preg_replace("/(<\\/head>)/i", $headerRequirements . "\\1", $content);
     $readyRequirements = $readyRequirements == "" ? "" : sprintf($ready_template, $readyRequirements);
     $readyRequirements = sprintf($script_template, $readyRequirements . $cleanRequirements);
     if ($this->force_js_to_bottom) {
         // Remove all newlines from code to preserve layout
         $readyRequirements = preg_replace('/>\\n*/', '>', $readyRequirements);
         // We put script tags into the body, for performance.
         // We forcefully put it at the bottom instead of before
         // the first script-tag occurence
         $content = preg_replace("/(<\\/body[^>]*>)/i", $readyRequirements . "\\1", $content);
     } elseif ($this->write_js_to_body) {
         // Remove all newlines from code to preserve layout
         $readyRequirements = preg_replace('/>\\n*/', '>', $readyRequirements);
         // We put script tags into the body, for performance.
         // If your template already has script tags in the body, then we put our script
         // tags just before those. Otherwise, we put it at the bottom.
         $p2 = stripos($content, '<body');
         $p1 = stripos($content, '<script', $p2);
         // @todo - should we move the inline script tags below everything else?
         // we could do this with regex, or a while loop...
         if ($p1 !== false) {
             $content = substr($content, 0, $p1) . $readyRequirements . substr($content, $p1);
         } else {
             $content = preg_replace("/(<\\/body[^>]*>)/i", $readyRequirements . "\\1", $content);
         }
     } else {
         $content = preg_replace("/(<\\/head>)/i", $readyRequirements . "\\1", $content);
     }
     return $content;
 }
 /**
  * Get files of the given type from the backend
  *
  * @param Requirements_Backend $backend
  * @param string $type js or css
  * @return array
  */
 protected function getBackendFiles($backend, $type)
 {
     $type = strtolower($type);
     switch (strtolower($type)) {
         case 'css':
             return $backend->getCSS();
         case 'js':
         case 'javascript':
         case 'script':
             $scripts = $backend->getJavascript();
             return array_combine(array_values($scripts), array_values($scripts));
     }
     return array();
 }
示例#15
0
 function testRequirementsBackend()
 {
     $basePath = $this->getCurrentRelativePath();
     $backend = new Requirements_Backend();
     $backend->javascript($basePath . '/a.js');
     $this->assertTrue(count($backend->get_javascript()) == 1, "There should be only 1 file included in required javascript.");
     $this->assertTrue(in_array($basePath . '/a.js', $backend->get_javascript()), "a.js should be included in required javascript.");
     $backend->javascript($basePath . '/b.js');
     $this->assertTrue(count($backend->get_javascript()) == 2, "There should be 2 files included in required javascript.");
     $backend->block($basePath . '/a.js');
     $this->assertTrue(count($backend->get_javascript()) == 1, "There should be only 1 file included in required javascript.");
     $this->assertFalse(in_array($basePath . '/a.js', $backend->get_javascript()), "a.js should not be included in required javascript after it has been blocked.");
     $this->assertTrue(in_array($basePath . '/b.js', $backend->get_javascript()), "b.js should be included in required javascript.");
     $backend->css($basePath . '/a.css');
     $this->assertTrue(count($backend->get_css()) == 1, "There should be only 1 file included in required css.");
     $this->assertArrayHasKey($basePath . '/a.css', $backend->get_css(), "a.css should be in required css.");
     $backend->block($basePath . '/a.css');
     $this->assertTrue(count($backend->get_css()) == 0, "There should be nothing in required css after file has been blocked.");
 }
示例#16
0
 function testBlockedInRender()
 {
     $backend = new Requirements_Backend();
     $backend->js('tests/phpunit/data/RequirementsTest_a.js');
     $backend->js('tests/phpunit/data/RequirementsTest_a.css');
     $backend->js('tests/phpunit/data/RequirementsTest_b.js');
     $backend->js('tests/phpunit/data/RequirementsTest_b.css');
     $backend->js('tests/phpunit/data/RequirementsTest_c.js');
     $backend->js('tests/phpunit/data/RequirementsTest_c.css');
     $backend->block('tests/phpunit/data/RequirementsTest_a.js');
     $backend->block('tests/phpunit/data/RequirementsTest_a.css');
     $backend->block('RequirementsTest_b.js');
     $backend->block('RequirementsTest_b.css');
     $html = $backend->render();
     $this->assertNotContains('tests/phpunit/data/RequirementsTest_a.js', $html, 'RequirementsTest_a.js was blocked and should not appear in rendered HTML');
     $this->assertNotContains('tests/phpunit/data/RequirementsTest_a.css', $html, 'RequirementsTest_a.css was blocked and should not appear in rendered HTML');
     $this->assertNotContains('tests/phpunit/data/RequirementsTest_b.js', $html, 'RequirementsTest_b.js was blocked and should not appear in rendered HTML');
     $this->assertNotContains('tests/phpunit/data/RequirementsTest_b.css', $html, 'RequirementsTest_b.css was blocked and should not appear in rendered HTML');
     $this->assertContains('tests/phpunit/data/RequirementsTest_c.js', $html, 'RequirementsTest_c.js should appear in rendered HTML');
     $this->assertContains('tests/phpunit/data/RequirementsTest_c.css', $html, 'RequirementsTest_c.css should appear in rendered HTML');
 }
示例#17
0
 public function testJsWriteToBody()
 {
     $backend = new Requirements_Backend();
     $backend->javascript('http://www.mydomain.com/test.js');
     // Test matching with HTML5 <header> tags as well
     $template = '<html><head></head><body><header>My header</header><p>Body</p></body></html>';
     $backend->set_write_js_to_body(false);
     $html = $backend->includeInHTML(false, $template);
     $this->assertContains('<head><script', $html);
     $backend->set_write_js_to_body(true);
     $html = $backend->includeInHTML(false, $template);
     $this->assertNotContains('<head><script', $html);
     $this->assertContains('</script></body>', $html);
 }