Dynamic content in css file - php

I am modifying a web app. It allows the user to input hex values for label-color, background-color and font-color. When the user input the values and clicks "update template". I need to be able to update the background color, label color and font color depending on the hex values that the user inputs. I am storing the label-color, background-color and font-color along with other template information in a MySQL table. I can do the following in the all the .phtml files that control the view:
$Idtemplate = $this->user->defaultTemplate;
$Objtemplate = new Template();
$Thetemplate = $Objtemplate->fetchRow("id=" . $Idtemplate);
$Title_Shiprequest = $Thetemplate->descriptionShipRequestTitle;
$clabel = $Thetemplate->descriptionlabelColor;
$cbackground = $Thetemplate->descriptionBkgColor;
$cfont =$Thetemplate->descriptionFontColor;
$clabel, $cbackground, $cfont are used for the color styling in the .phtml.
The problem is there are about 34 .phtml files. If I want to do it this way I have to find the div classes responsible for the colors and do the respective changes there. It sounds like a very inefficient and lengthy solution to me.
But there are about 4-5 classes in the css file where all the color values are defined and used. Its much easier and efficient for me to do something like the above mentioned code in css file (the only problem is it does not work in css file) and refer to them like below (i have renamed my common.css as common.php):
.panel1
{
width: auto;
height: 22px;
background-color: <?= $cbackground ?>;
padding: 5px;
}
When I try to include the code to fetch color information from the database it messes up all the formatting as if the program cant see my .css file. My hunch is that I am not allowed to instantiate an object inside a heredoc in a css even though I renamed it as common.php. What could be a workaround solution in this situation?
UPDATE:
Well I was already including header("Content-type: text/css"); But i tried the followings again just to make sure:
<?php
header("Content-type: text/css");
$Idtemplate = $this->user->defaultTemplate;
$Objtemplate = new Template();
$Thetemplate = $Objtemplate->fetchRow("id=" . $Idtemplate);
$clabel = $Thetemplate->descriptionlabelColor;
$cbackground = $Thetemplate->descriptionBkgColor;
$cfont =$Thetemplate->descriptionFontColor;
?>
<style type='text/css'>
.text4
{
color: <?=$clabel?>;// font and bkg colors are referred to likewise
}
</style>
Unfortunately this did not work. I also tried:
<?php
header("Content-type: text/css");
include('C:/sr/public/css/getdata.php');
?>
<style type='text/css'>
.text4
{
color: <?=$clabel?>;// font and bkg colors are referred to likewise
}
</style>
where getdata.php has the code:
<?php
$Idtemplate = $this->user->defaultTemplate;
include('C:/sr/application/models/Template.php');
$Objtemplate = new Template();
$Thetemplate = $Objtemplate->fetchRow("id=" . $Idtemplate);
$clabel = $Thetemplate->descriptionlabelColor;
$cbackground = $Thetemplate->descriptionBkgColor;
$cfont =$Thetemplate->descriptionFontColor;
?>
It did not work either. As a fourth variation I tried to define a function and call it from common.php:
<?php
function getLabelColor() {
$clabel = '#001122';
return $clabel;
}
function getBkgColor() {
$cbackground = '#002233';
return $cbackground;
}
function getFontColor() {
$cfont = '#004455';
return $cfont;
}
?>
where common.php has :
<?php
header("Content-type: text/css");
include('C:/sr/public/css/getdata.php');
?>
<style type='text/css'>
.text2
{
color: <?php echo getLabelColor();?>; /* Bkg and font colors are referred to likewise*/
}
</style>
Surprising this worked. But when I tried to replace
$clabel = '#001122';
(along with $cbackground and $cfont in the respective functions) with
$Idtemplate = $this->user->defaultTemplate;
$Objtemplate = new Template();
$Thetemplate = $Objtemplate->fetchRow("id=" . $Idtemplate);
$clabel = $Thetemplate->descriptionlabelColor;
return ('#'.$clabel);
it stopped working. So I moved getdata.php to models made class that included all the above mentioned functions:
<?php
Class fetchData extends Template
{
function getLabelColor() {
$Idtemplate = 101// I had assign a known value here. I was not able to use $this->user->defaultTemplate; Not sure why I wont be able to use $this
$Objtemplate = new Template();
$Thetemplate = $Objtemplate->fetchRow("id=" . $Idtemplate);
$clabel = $Thetemplate->descriptionlabelColor;//for future usage for dynamic color
return ('#'.$clabel);
}
function getBkgColor() {
$Idtemplate = 101// I had assign a known value here. I was not able to use $this->user->defaultTemplate; Not sure why I wont be able to use $this
$Objtemplate = new Template();
$Thetemplate = $Objtemplate->fetchRow("id=" . $Idtemplate);
$cbackground = $Thetemplate->descriptionBkgColor;//for future usage for dynamic color
return ('#'.$cbackground);
}
function getFontColor() {
$Idtemplate = 101// I had assign a known value here. I was not able to use $this->user->defaultTemplate; Not sure why I wont be able to use $this
$Objtemplate = new Template();
$Thetemplate = $Objtemplate->fetchRow("id=" . $Idtemplate);
$cfont =$Thetemplate->descriptionFontColor;//for future usage for dynamic color
return ('#'.$cfont);
}
}
?>
I was calling the functions like below:
include('C:/sr/application/models/getdata.php');
$datafetchObj = new fetchData();
$clabel = $datafetchObj->getLabelColor(); //purple 51:0:153
$cbackground = $datafetchObj->getBkgColor(); //Light blue 102:102:204
$cfont = $datafetchObj->getFontColor();
This only worked from .phtml but not from common.php. I suppose common.php is NOT allowed to instantiate an object.
PS: This what my common.php call looks like:
<link rel="stylesheet" type="text/css" href="<?php echo $this->baseUrl();?>/css/common.php" />

You just use
<link rel="stylesheet" type="text/css" media="screen" href="/css/mycss.php" />
and then you can use php inside your css. you could add appropriate headers (text/css) with header in php.
// mycss.php
<?php
header("content-type:text/css");
?>
<style type='text/css'>
// Stylesheet
</style>

Add this line as a first line of page in common.php:
header("Content-type: text/css");

I was having the same problem as you, then I changed the hex color to the name of the color in the database and everything worked fine. I don't know why the hex color can't come out like other texts, but anyways, simply change the color the name:
E.I.: white for #FFFFFF
I hope that worked out for you.
EDIT: I thought that could be helpful too,
When inserting to database, use hexdec() http://www.php.net/manual/en/function.hexdec.php and when displaying from database, use dechex() http://php.net/manual/en/function.dechex.php .
dechex will return the hex without the hash (#) though, so you might need to print it like that:
<?php echo "#".dechex($decimal_number); ?>
I hope that was useful buddy.

Related

How to include a PHP object in CSS?

When using an external stylesheet, is it possible to use a PHP object within CSS - without creating another object?
I have found workarounds with internal and inline CSS (e.g. How to include PHP code in CSS?) Below is some minimal code to show the problem and the workarounds I have found thus far.
in MyClass.php:
class MyClass{
public $color = "blue";
}
in PHP/HTML file:
<?php
include_once('MyClass.php');
$myClass = new MyClass();
?>
... (in head - internal CSS workaround):
<style type="text/css">
h1{color: <?php echo $myClass->color;?>;}
</style>
... (in head - external CSS workaround):
<link rel="stylesheet" href="external.css") />
... (in body):
<h1> 1. Internal </h1>
<h2 style="color:<?php echo $myClass->color;?>"> 2. Inline </h2>
<h3> 3. External </h3>
In external.css [here is the "problem" - I need to create a new object]:
<?php
header('Content-type: text/css');
include('myClass.php');
$myClass = new MyClass(); //<--ANOTHER OBJECT
?>
h3 {
color: <?=$myClass->color?>;
}

How can I execute a PHP file before using its content with another file?

Situation
I’m mixing HTML & CSS with PHP variables, so that I can manage a lot of settings with just one config file. This is all working fine, but I’m trying to merge and minify the CSS now. And this causes a problem.
Problem
The variables won’t be echoed into the compressed sheet because the PHP script won't be executed. And that is because file_get_contents() converts the content into a string.
Question
Is it in some way possible to execute the files first, and then grab their contents? Or grab their contents in another way, a way that they still will be executed?
Files
config.php
$priColor = '#000';
base-stylesheet.php
/* CSS header defined */
/* config.php included */
body{
background-color: <?= $priColor ?>;
}
specific-stylesheet.php
/* CSS header defined */
/* config.php included */
.site-specific-element{
background-color: <?= $priColor ?>;
}
minified-stylesheets.php
// Set files that must be minified
$cssFiles = array(
"base-styleseet.php",
"specific-stylesheet.php"
);
// Get those files
$buffer = "";
foreach ($cssFiles as $cssFile) {
$buffer .= file_get_contents($cssFile);
}
// Minify and echo them
minifyCSS($buffer);
echo $buffer;
index.php
<link rel="stylesheet" href="minified-stylesheets.php">
I think what you need to do is include the file into a PHP buffer and then minify the buffer
// Set files that must be minified
$cssFiles = array(
"base-styleseet.php",
“specific-stylesheet.php"
);
// Get those files
ob_start();
foreach ($cssFiles as $cssFile) {
include($cssFile);
}
// Minify and echo them
$css = minifyCSS(ob_get_clean());
echo $css;
You already are familiar with the ob_start() method.
But I will show a better alternative (and faster):
Your main file:
$cssFiles = array(
"base-styleseet.php",
"specific-stylesheet.php"
);
$buffer = "";
foreach ($cssFiles as $cssFile) {
$buffer .= include($cssFile);
}
minifyCSS($buffer);
echo $buffer;
Well, nothing much here. Just added a include() there...
But it won't work as intended, unless you do like this, for every file:
Create a heredoc with all the content
Return it
Using the base stylesheet as an example:
<?php
//remember to escape the { chars
return <<<CSS
/* CSS header defined */
/* config.php included */
body\{
background-color: $priColor;
/* with an array */
background-image: url('{$images['print']}');
/* or */
background-image: url('$images[print]');
\}
CSS;
* Ignore the broken syntax highlight
And you are done.
No more nasty ob_start()!!!
Also, CSS comments use the /* */ syntax, // will be evaluated as an invalid CSS selector.
file_get_contents() will literally read the content of a file and place the content into a string. What you need to use is include(). This will parse the contents of the file.

Using css variables with php in joomla 3 template

My idea is to use template parameter in joomla to set the color for a background, text or buttons.
I want to define a css class instead of each time using style="background-color:<?php echo $buttoncolor ?>;" as I don't want to write countless template overrides.
I believe that could be very usefull feature.
The parameter in my templateDetails.xml looks like
<field name="buttoncolor" type="color" default="#309000"
label="TPL_BUTTON_COLOR_LABEL"
description="TPL_BUTTON_COLOR_DESC" />
The idea how to use php variable in css I found on CSS-Tricks
To use a php variable within a css I linked to this file in my index.php
<link rel="stylesheet" href="<?php echo $this->baseurl ?>/templates/<?php echo $this->template; ?>/css/style.php" type="text/css" />
My style.php looks like:
<?php
header("Content-type: text/css; charset: UTF-8");
$buttoncolor = $this->params->get("buttoncolor");
?>
.buttoncolor {background-color: <?php echo $this->params->get('buttoncolor'); ?>;}
Usally I set a variable to a template parameter in the index.php like
<?php
//parameter
$app = JFactory::getApplication();
$doc = JFactory::getDocument();
$params = $app->getParams();
$buttoncolor = $this->params->get('buttoncolor');
?>
Unfortunately I got the following error:
Fatal error: Using $this when not in object context in style.php
Any ideas, workaround and help is highly appreciated!
Please try to remove $this. Your code has to be:
$app = JFactory::getApplication();
$template = $app->getTemplate(true);
$params = $template->params;
$buttoncolor = $params->get("buttoncolor");
Joomla has a specific way to set css style. You have to do it like:
$document = JFactory::getDocument();
$style = ".buttoncolor {background-color: ".$buttoncolor."}";
$document->addStyleDeclaration($style);
Good Luck!

Manually rendering Zend_View with layout enabled

I'm creating a mail service within my application that has the body of the email stored in the database prior to sending it out to recipients.
Each mail body is a partial view script that has the necessary parameters injected into it via Zend_View.
What I want to do is create a 'mail' layout that can wrap around each of these partials,
but I can only seem to get either the layout content or the view content; not both at once.
What I've got
$scriptPath = 'test_mail';
$view = Zend_Controller_Front::getInstance()->getParam('bootstrap')->getResource('view');
$view->setScriptPath(APPLICATION_PATH . '/modules/mail/views/scripts/partials/');
$view->layout()->setLayout('mail');
var_dump($view->layout()->render($scriptPath));
However, all I receive is the view script content.
My layout is looking something like this:
<table class="mail">
<!-- Snip -->
<?php echo $this->layout()->content; ?>
<!-- Snip -->
</table>
I know this is possible. I don't want to do:
$layout->content = $view->render($scriptPath);
I assume I'm going the wrong way about this. Is it that I need/ don't have the layout controller plugin registered and somehow need to trigger this to get the output?
I suppose I could just create a custom layout class and take care of the rendering myself but wanted to see what others said first.
Any tips? Thanks!
I am using email layout, multiple view templates for different kinds of emails and extended Zend_Mail class for setting desirable body:
class MyMail extends Zend_Mail
{
public function setBodyView($script, $params = array())
{
$layout = new Zend_Layout(array('layoutPath' => APPLICATION_PATH . '/layouts/scripts'));
$layout->setLayout('email'); // Your email layout
$view = new Zend_View();
$view->setScriptPath(APPLICATION_PATH . PATH_TO_MAIL_TEMPLATES);
foreach ($params as $key => $value) {
$view->assign($key, $value);
}
$layout->content = $view->render($script . '.phtml');
$html = $layout->render();
$this->setBodyHtml($html);
}
}
I using %mail_body% pattern in my mail template.
$layout = Zend_Layout::getMvcInstance();
$view = $layout->getView();
$mail_template = $view->render('template.phtml');
$returnYourReadyTemplate = str_replace('%mail_body%', $mail_body, $mail_template);
in template.phtml :
<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body >
<div style="margin:30px 20px 10px 20px">
%mail_body%
</div>
</body>
</html>
Hope this helps you!

CSS minify with PHP extension

How can I minify a .php file with CSS contents?
Currently I get a 400 error.
Normally I call minify like this
<link rel="stylesheet" type="text/css"
href="{$workspace}/min/f=workspace/css/common.css" />
EDIT
The answer is changing the minify source code, but what is the change I should make?
In other words.. this call should work and process as CSS..
<link rel="stylesheet" type="text/css"
href="{$workspace}/min/f=workspace/css/common.php" />
Maybe with an optional declaration?
<link rel="stylesheet" type="text/css"
href="{$workspace}/min/f=workspace/css/common.php&type=css" />
EDIT
I created the project here # https://github.com/into/less-less
Your CSS+PHP script outputs CSS only after it's requested from a server and parsed by PHP. Minify reads files directly from the server, skipping the HTTP request. So I see two paths:
Less optimal [?]: make minify download the CSS like this:
<link rel="stylesheet" type="text/css" href="{$workspace}/min/f=http://site.com/workspace/css/common.php" />
Include Minify lib in your common.php file and use its classes (e.g. Minify_CSS) before output. Something like echo Minify_CSS::minify($css)
Update:
Your example repo contains a strange file name which wouldn't let me pull/push appropriately, so here's the changed report.php:
<pre>
<strong>LESS in</strong>
<?= file_get_contents('workspace/less/common.less') ?>
- - - - -
<strong>CSS out</strong>
<?
require 'workspace/php/lessc.inc.php';
$lc = new lessc();
$contents = file_get_contents( 'workspace/less/common.less' );
$css = $lc->parse( $contents );
echo $css;
?>
<strong>Minified</strong>
<?php
require 'workspace/min/lib/Minify/CSS/Compressor.php';
echo Minify_CSS_Compressor::process($css);
?>
</pre>
No, you can't easily do it as minify heavily depends on file extensions (css,js,?). For example it is used to determine what HTTP headers send to client(application/x-javascript,text/css,?), what minifier class to use, is this file safe to parse etc.
But I'm almost certain that this situation can be avoided. Could you please describe why exactly you want to do this?
If you insist on doing it this way I can propose a few dirty hacks to make it work, but it requires changing minify's source code so I don't really know if that is a good idea.
Upd:
There is no nice way to change this source: it has really bad structure. In minify v2.1.3 you can simply change the following:
Path: lib/Minify/Controller/Base.php##Minify_Controller_Base::_fileIsSafe()
return in_array(strrev($revExt), array('js', 'css', 'html', 'txt'));
-->
return in_array(strrev($revExt), array('js', 'css', 'html', 'txt', 'php'));
Path: lib/Minify/Controller/MinApp.php##Minify_Controller_MinApp::setupSources()
preg_match('/^[^,]+\\.(css|js)(?:,[^,]+\\.\\1)*$/', $_GET['f'])
-->
preg_match('/^[^,]+\\.(css|js|php)(?:,[^,]+\\.\\1)*$/', $_GET['f'])
Path: lib/Minify/##Minify_Source::__construct()
case 'css' : $this->contentType = 'text/css';
-->
case 'php': case 'css': $this->contentType = 'text/css';
and everything will work, but you must set $min_serveOptions['minApp']['allowDirs'] in configuration carefully as any user may be able to view any php file from this directories.
Using CSS Min, you are freely could do whatsoever and you could also "processing" your stlyesheet in php script, then minify it on the fly : its DEAD simple to do that, and guess what, it just A SINGLE FILE.
Another way is, dont use any PHP script to process or doing some logical at your css file, instead, you could have separated small css file then you just load whatever you want by building new cache file or just combine and output the link tag.
However, if you are now have something like this in your common.php (php file/script that outputing the css, yes?)
<?php
$style = '';
$bodyStyle = 'body {
background-color: #000;
margin: 40px;
font: 13px/20px normal Helvetica, Arial, sans-serif;
color: #fff;
}';
// I assumed you are about proccesing something here..
// ...
// Then you merged all style into one string, and output it as css file
$style = $bodyStyle + $otherStyle + $whateverStyle;
header('Content-Type: text/css');
echo $style;
?>
And you still want to make your app bloated and make your code more unreadable (wait, there still more...), also want to modify Minify class/lib to minify and cache you pseudo-css-php, then you need to "hacking" the source as follow :
lib/Minify/Controller/Base.php : 135, change to :
return in_array(strrev($revExt), array('js', 'css', 'html', 'txt', 'php'));
lib/Minify/Controller/MinApp.php : 75, change to :
! preg_match('/^[^,]+\\.(css|js|php)(?:,[^,]+\\.\\1)*$/', $_GET['f'])
lib/Minify/Source.php, change several things :
Add one variable as a PHP flag, in , after line 41 perhaps
/**
* #var bool
*/
public $isPHP = FALSE;
In same file, at line : 67, add a condition :
case 'php' : $this->isPHP = TRUE;
$this->contentType = 'text/css';
break;
Last, replace getContent() function, into :
public function getContent()
{
if($this->isPHP)
{
include($this->filepath);
}
else
{
$content = (null !== $this->filepath)
? file_get_contents($this->filepath)
: ((null !== $this->_content)
? $this->_content
: call_user_func($this->_getContentFunc, $this->_id)
);
}
// remove UTF-8 BOM if present
return (pack("CCC",0xef,0xbb,0xbf) === substr($content, 0, 3))
? substr($content, 3)
: $content;
}
You also need to change your common.php into Minify spec, so now, your common.php should looks like :
You need to put all your stylesheet as string and assign it into $content variable
<?php
//$style = '';
$bodyStyle = 'body {
background-color: #000;
margin: 40px;
font: 13px/20px normal Helvetica, Arial, sans-serif;
color: #fff;
}';
// I assumed you are about proccesing something here..
// ...
// Then you merged all style into one string, and output it as css file
// $style = $bodyStyle + $otherStyle + $whateverStyle;
// header('Content-Type: text/css');
// echo $style;
$content = $bodyStyle + $otherStyle + $whateverStyle;
?>
Yes, there is one and it works pretty well:
https://github.com/c9s/pecl-cssmin
The API is pretty simple:
<?php
echo cssmin("body { .... } .rule { } .rule2 { color: #fff; }");

Categories