$css = @file_get_contents($cacheLocation); } } // Load and CSS-Magic-ify the CSS file. If an outer file, just cache it if (empty($css)) { require $wpUnited->get_plugin_path() . 'css-magic.php'; if ($pkg == 'phpbb') { $packagePath = $wpUnited->get_setting('phpbb_path'); $packageUrl = $phpbbForum->get_board_url(); } else { $packagePath = $wpUnited->get_wp_path(); $packageUrl = $wpUnited->get_wp_base_url(); } $processImports = $useTV == -1; $cssMagic = new CSS_Magic($processImports, $packageUrl, $packagePath); if ($cssMagic->parseFile($cssFileToFix)) { if ($pos == 'inner') { // Apply Template Voodoo if ($useTV > -1) { if (!apply_template_voodoo($cssMagic, $useTV)) { // set useTV to -1 so that cache name reflects that we weren't able to apply TemplateVoodoo $useTV = -1; $tvFailed = true; } } // Apply CSS Magic $cssMagic->makeSpecificByIdThenClass('wpucssmagic', false); } if ($islandBlock) { $cssMagic->makeSpecificByClass('wpuisle2', false); $cssMagic->makeSpecificByClass('wpuisle', false);
/** * CSS MAGIC * * We now have properly separated inner/outer content * * We now identify all the stylesheets and redirect them to CSS Magic. * We don't parse them now, as style.php is used for phpBB styles. * * Once they have been parsed by CSS Magic, on subsequent run-throughs here, * we can read CSS Magic's cache and look at the stylesheets for conflicting * classes and IDs. Then, we modify the templates accordingly, and instruct CSS Magic * to make additional changes to the CSS the next time around. */ function wpu_css_magic() { global $wpUnited; $wpuCache = WPU_Cache::getInstance(); /** * Get all links to stylesheets, and prepare appropriate replacement links to insert into the page content * The generated CSS links to insert into the HTML will need to carry information for the browser on the * physical disk location of the CSS files on the server. * * We cannot allow browsers to just request any file on the server by filename, so get_stylesheet_links pre-approves the * files and stores them in the DB under "style keys". Browsers then only need to know the * appropriate style key, not the filename */ $innerSSLinks = wpu_get_stylesheet_links($wpUnited->get_inner_headinfo(), 'inner'); // also grep all inline css out of headers $inCSSInner = wpu_extract_css($wpUnited->get_inner_headinfo()); /** * Template Voodoo */ if ($wpUnited->get_setting('templateVoodoo')) { //For template voodoo, we also need the outer styles $outerSSLinks = wpu_get_stylesheet_links($wpUnited->get_outer_content(), 'outer'); $inCSSOuter = wpu_extract_css($wpUnited->get_outer_content()); // First check if the cached CSS Magic files exist, and insert placeholders for TV cache location if they do $foundInner = array(); $foundOuter = array(); foreach ((array) $innerSSLinks['keys'] as $index => $key) { if ($found = $wpuCache->get_css_magic($wpUnited->get_style_key($key), 'inner', -1)) { $foundInner[] = $found; $innerSSLinks['replacements'][$index] .= '[*FOUND*]'; } else { $innerSSLinks['replacements'][$index] .= '-1'; } } foreach ($outerSSLinks['keys'] as $index => $key) { if ($found = $wpuCache->get_css_magic($wpUnited->get_style_key($key), 'outer', -1)) { $foundOuter[] = $found; } } /** * Now we create a unique hash based on everything we've found, and use this to * store our Template Voodoo instructions. * We append the template voodoo hash key to the end of the redirected stylesheets */ $tplVoodooKey = $wpuCache->get_template_voodoo_key(TEMPLATEPATH, $foundInner, $foundOuter, (array) $inCSSInner['orig'], (array) $inCSSOuter['orig']); $innerSSLinks['replacements'] = str_replace('[*FOUND*]', $tplVoodooKey, $innerSSLinks['replacements']); if ((sizeof($foundInner) || $inCSSInner['orig']) && (sizeof($foundOuter) || $inCSSOuter['orig'])) { $classDupes = array(); $idDupes = array(); if ($templateVoodoo = $wpuCache->get_template_voodoo($tplVoodooKey)) { /** * The template voodoo instructions already exist for this CSS combination */ if (isset($templateVoodoo['classes']) && isset($templateVoodoo['ids'])) { $classDupes = $templateVoodoo['classes']; $idDupes = $templateVoodoo['ids']; } } else { /** * We don't have template voodoo for this yet, we need to do some legwork * and generate a set of instructions. * @todo move to separate function, generate_instructions(). */ $outerCSS = new CSS_Magic(); $innerCSS = new CSS_Magic(); foreach ($foundInner as $index => $cacheFile) { $innerCSS->parseFile($cacheFile); } foreach ($foundOuter as $index => $cacheFile) { $outerCSS->parseFile($cacheFile); } foreach ($inCSSInner['css'] as $index => $css) { $innerCSS->parseString($css); } foreach ($inCSSOuter['css'] as $index => $css) { $outerCSS->parseString($css); } $innerCSS->removeCommonKeyEl('#wpucssmagic .wpucssmagic'); $ignores = array('wpucssmagic', 'wpuisle'); $innerKeys = $innerCSS->getKeyClassesAndIDs(); $outerKeys = $outerCSS->getKeyClassesAndIDs($ignores); $innerCSS->clear(); $outerCSS->clear(); unset($innerCSS, $outerCSS); $classDupes = array_intersect($innerKeys['classes'], $outerKeys['classes']); $idDupes = array_intersect($innerKeys['ids'], $outerKeys['ids']); unset($innerKeys, $outerKeys); // save to cache $wpuCache->save_template_voodoo(array('classes' => $classDupes, 'ids' => $idDupes), $tplVoodooKey); } /** * Now, we can modify the page, removing class and ID duplicates from the inner content */ foreach ($classDupes as $dupe) { $findClass = substr($dupe, 1); //remove leading '.' $wpUnited->set_inner_content(preg_replace('/(class=["\']([^\\s^\'^"]*\\s+)*)' . $findClass . '([\\s\'"])/', '\\1wpu' . $findClass . '\\3', $wpUnited->get_inner_content())); } foreach ($idDupes as $dupe) { $findId = substr($dupe, 1); //remove leading '.' $wpUnited->set_inner_content(preg_replace('/(id=["\']\\s*)' . $findId . '([\\s\'"])/', '\\1wpu' . $findId . '\\2', $wpUnited->get_inner_content())); } } } // end template voodoo /** * Now we can apply the CSS magic to any inline CSS */ $useTVStr = $wpUnited->get_setting('templateVoodoo') ? 'TV' : ''; $tvKey = $wpUnited->get_setting('templateVoodoo') ? $tplVoodooKey : -1; $numFixes = 0; foreach ($inCSSInner['css'] as $index => $innerCSSItem) { if ($inlineCache = $wpuCache->get_css_magic("{$index}-{$useTVStr}", 'inline', $tvKey)) { $result = @file_get_contents($inlineCache); } else { $cssM = new CSS_Magic(); $cssM->parseString($innerCSSItem); /** * @todo could split out to templatevoodoo file */ if ($wpUnited->get_setting('templateVoodoo')) { if (isset($classDupes) && isset($idDupes)) { $finds = array(); $repl = array(); foreach ($classDupes as $classDupe) { $finds[] = $classDupe; $repl[] = ".wpu" . substr($classDupe, 1); } foreach ($idDupes as $idDupe) { $finds[] = $idDupe; $repl[] = "#wpu" . substr($idDupe, 1); } $cssM->modifyKeys($finds, $repl); } } $cssM->makeSpecificByIdThenClass('wpucssmagic', false); $result = $cssM->getCSS(); // save to cache $wpuCache->save_css_magic($result, "{$index}-{$useTVStr}", 'inline', $tvKey); } if (!empty($result)) { //$result = '<style type="text/css">' . $result . '</style>'; $wpUnited->set_inner_headinfo(str_replace($inCSSInner['orig'][$index], $result, $wpUnited->get_inner_headinfo())); $numFixes++; } } // Store the updated style keys $wpUnited->commit_style_keys(); // add link to reset stylesheet $reset = "<link href=\"{$wpUnited->get_plugin_url()}theme/reset.css\" rel=\"stylesheet\" media=\"all\" type=\"text/css\" />"; $wpUnited->set_inner_headinfo($reset . $wpUnited->get_inner_headinfo()); //write out the modified stylesheet links $wpUnited->set_inner_headinfo(str_replace($innerSSLinks['links'], $innerSSLinks['replacements'], $wpUnited->get_inner_headinfo())); if ($wpUnited->get_setting('templateVoodoo')) { $wpUnited->set_outer_content(str_replace($outerSSLinks['links'], $outerSSLinks['replacements'], $wpUnited->get_outer_content())); } /** * Elements (mainly third-party BBCodes) with height="" cannot override the height CSS rule set in CSS Magic's reset.css * This adds an inline CSS style attribute to any such elements * If the element already has an inline style attribute, the height rule will be appended to it */ $withInline = preg_replace_callback('/((<[^>]+\\b)(?=height\\s?=\\s?[\'"]?\\s?([0-9]+)\\s?[\'"]?)([^>]*?))(\\/?\\s*>)/', create_function('$m', 'if(preg_match(\'/(style\\s?=\\s?[\\\'"]([^\\\'"]+))([\\\'"])/\', $m[1], $r)) return str_replace($r[0], "{$r[1]};height:{$m[3]}px;{$r[3]}", $m[1]) . $m[5]; return $m[1] . \' style="height:\' . $m[3] . \'px;" \' . $m[5];'), $wpUnited->get_inner_content()); //same with width $withInline = preg_replace_callback('/((<[^>]+\\b)(?=width\\s?=\\s?[\'"]?\\s?([0-9]+)\\s?[\'"]?)([^>]*?))(\\/?\\s*>)/', create_function('$m', 'if(preg_match(\'/(style\\s?=\\s?[\\\'"]([^\\\'"]+))([\\\'"])/\', $m[1], $r)) return str_replace($r[0], "{$r[1]};width:{$m[3]}px;{$r[3]}", $m[1]) . $m[5]; return $m[1] . \' style="width:\' . $m[3] . \'px;" \' . $m[5];'), $withInline); //and bgcolor $withInline = preg_replace_callback('/((<[^>]+\\b)(?=bgcolor\\s?=\\s?[\'"]?\\s?([0-9]+)\\s?[\'"]?)([^>]*?))(\\/?\\s*>)/', create_function('$m', 'if(preg_match(\'/(style\\s?=\\s?[\\\'"]([^\\\'"]+))([\\\'"])/\', $m[1], $r)) return str_replace($r[0], "{$r[1]};background-color:{$m[3]}px;{$r[3]}", $m[1]) . $m[5]; return $m[1] . \' style="background-color:\' . $m[3] . \'px;" \' . $m[5];'), $withInline); $wpUnited->set_inner_content($withInline); }