create css with php laravel - php

i need create get css files with laraven in my controller, because i have one problem my return result is one normal file (text file) and not a css file
my routes.php file contain:
Route::get('/css/{css}.css', 'FileController#GetCss')
->where('css','[A-Za-z]+');
FileController.php:
<?php
class FileController extends \BaseController {
public function GetCss($css)
{
$file = File::get(app_path()."\css\\".$css.".css");
return $file;
}
}
and my css.css file contain:
body
{
background: #f00;
}
browser return is:
body{ background: #f00; }
and source (inspect element / ctrl+u):
body
{
background: #f00;
}
what I must do to work as a css file?

Your question need more clarification, I guess you are trying to build a CDN or something like that.
When you say "what I must do to work as a css file?", I think you need to specify a header for the response:
public function GetCss($css)
{
$file = File::get(app_path()."\css\\".$css.".css");
$response = Response::make($file);
$response->header('Content-Type', "text/css");
return $response;
}

Related

Laravel dom crawler search img in javascript

I have part of html content:
$("table:first").after("<img src=\"https://example.com/images/banners/image.png\" alt=\"Example\" width=\"88px\" style=\"display: block; margin-left: auto; margin-right: auto; \">");
I need search img and attr src with value https://example.com/images/banners/image.png.
I do:
$html = $content ? new Crawler($content) : [];
$res = false;
foreach ($html->filter('img')->previousAll() as $element) {
if (in_array($element->attr('src'), [asset('images/banners/image.png')])) {
$res = true;
} else {
$res = false;
}
}
But I get false. Why? If img is not inside in jQuery, then everything is working. But if img is in jquery then how can I get true?
It looks like the symfony/dom-crawler package doesn't support Javascript. It only loads static html and xml documents, and doesn't load and render Javascript like a browser would. It looks like fabpot/goutte or symfony/panther are packages that you can use together with dom-crawler to crawl sites where you want the Javascript to be loaded and run. They use BrowserKit in the background which simulates a browser.

How to compile SCSS with scssphp

I'm currently trying to compile some SCSS which I'm receiving via a form request. The current workflow is that the user submits form data as follows:
{"$background_color":"#f3f3f3","$logo_url":"https:\/\/logo.co\/random"}
I then transform this input to the following:
$background_color: '#f3f3f3';
$logo_url: 'https://logo.co/random'
This should be valid for the purposes of compiling it to CSS so I run it through SCSSPHP with the following:
$scss->addImportPath(Storage::disk('tmp'));
$output = $scss->compile("#import 'test'; $statement ");
No errors are triggered when I run this and the output is:
#import 'test';
My test.scss is as follows:
$background_colour: 'red'
$logo_url: 'https://test.com'
.logo {
background-image: $logo_url;
}
.background_colour {
background-colour: $background_colour;
}
What am I doing wrong here?
The problem is that you're not passing a string to this function.
Parse your scss as a string by using the function file_get_contents
require_once "scssphp/scss.inc.php";
use Leafo\ScssPhp\Compiler;
$scss = new Compiler();
// Gets the content of the scss file in string format
$scss_string = file_get_contents(path/to/scss.file);
echo $scss->compile($scss_string);

unrequire a php file

Im working on a website - just learning to improve my coding.
I have a routing system which works like this:
/config/routes.php:
$route->add('/' , function() {
require_once("/application/pages/index.php");
});
$route->add('/register', function() {
require_once("/application/pages/register.php");
});
$route->add('/login', function() {
require_once("/application/pages/login.php");
});
$route->add('/logout', function() {
require_once("/application/pages/logout.php");
});
$route->add('/panel', function() {
require_once('/application/pages/panel/index.php');
});
And in my index.php:
require_once('application/pages/header.php');
include('config/routes.php');
require_once('application/pages/footer.php');
Everything works fine but I need a different header.php and footer.php for when the user goes into the panel. file: /application/pages/panel/index.php
When I require_once a new header file in the panel/index.php then both the new and old header file is loaded. How can I unrequire the header and footer files in the /panel/index.php so I can require different ones? Any suggestions?
Note: Routing comes from an MVC design pattern, you should keep your controllers separate from your views.
Templates and Views could be kept separate, also. This meaning our directory set-up can look something like this:
- Templates
- header_one.php
- footer_one.php
- header_two.php
- footer_two.php
- Views
- index.php
- someOtherBody.php
Here is a simple, but unfinished (that is your challenge) example of an Object that could do what I am explaining:
class Page {
private $template_path = dirname(dirname(__FILE__)) . '/templates/';
private $view_path = dirname(dirname(__FILE__)) . '/views/';
protected $header;
protected $footer;
protected $body;
public function setHeader($file_name)
{
if(is_readable($this->template_path . $file_name))
{
$this->header = $this->template_path . $file_name;
return $this;
}
// add an exception
}
/* TODO: */
public function setFooter() {}
public function setBody() {}
/* Render page */
public function render()
{
$page = [$this->header,$this->body,$this->footer];
foreach($page as $file)
{
require_once($file);
}
}
}
The idea here is that we can set our page layout, using the above object, within the route method closure, then render / require all the files after the logic.
$route->add('/', function() {
$page = new Page();
$page->setHeader('header_one.php')
->setBody('index.php')
->setFooter('footer_one.php');
/* todo: add your logic here */
$page->render();
});
Each route can now have its own header, footer and body.
Hope this helped.
At your place, I will do something like that :
Use out buffer and check if the file is already required. I give you an quick example but adapt the code for you.
And check the function : http://php.net/manual/en/function.get-included-files.php
$route->add('/panel', function() {
include_once('YOUR_SPECIFIC_PATH/header.php');
require_once('/application/pages/panel/index.php');
include_once('YOUR_SPECIFIC_PATH_header/footer.php');
});
And :
ob_start();
include_once('config/routes.php');
$mainContent = ob_get_contents();
ob_end_clean();
include_once('application/pages/header.php');
echo $mainContent;
include_once('application/pages/footer.php');
I've not the time for help more sorry but I can explain later if you need
This solution requires you to have a header.php and footer.php in each folder where your sub-controllers (application/<module name>/index.php) are.
index.php only call your sub-controllers via routing:
// require not include, because "no routing" = "no web site" ;)
require_once('config/routes.php');
application/pages/index.php include appropriate header/footer w/ relative path
require_once('header.php');
// page code
require_once('footer.php');
application/register/index.php include appropriate header/footer w/ relative path
require_once('header.php');
// page code
require_once('footer.php');
etc
#KDOT , thanks you for your help but using your code I was getting an error that I could not fix:
Call to a member function setBody() on null
but thanks to your code, I managed to rewrite the class my way and now it works ;)
Thanks again #KDOT !
If anyone needs it:
class Page {
private $TEMPLATE_PATH = '/application/templates/';
private $VIEW_PATH = '/application/views/';
protected $header;
protected $footer;
protected $body;
public function __construct($header_file, $body_file, $footer_file) {
$this->header = $this->TEMPLATE_PATH . $header_file;
$this->body = $this->VIEW_PATH . $body_file;
$this->footer = $this->TEMPLATE_PATH . $footer_file;
}
public function render(){
$page = [$this->header, $this->body, $this->footer];
foreach($page as $file) {
require_once($file);
}
}
}
and:
$route->add('/', function() {
$page = new Page('header.php', 'home.php', 'footer.php');
$page->render();
});

Autoload a view on every page with codeigniter

So I have my views split up basically between three (3) files:
-- Header file
$this->load->view('templates/header', $data);
-- Main Body file
$this->load->view('login_view', $data);
-- Footer file
$this->load->view('templates/footer', $data);
Now I just recently started building, but I've noticed it's really annoying to retype the header and footer on every controller to tell it to load. Is there a way to automatically load the header and footer view on every request?
I found an article long time ago, but i can't seem to find it now, basically the author, (which i forgot) override the showing of output. this method of output will access your views regarding the given controller/method and will try to search in your views directory automatically.
Use at your own risk
Application/core/MY_COntroller.php
----------------------------------------------------------------------------
class MY_Controller Extends CI_Controller
{
protected $layout_view = 'layouts/application'; // default
protected $content_view =''; //data
protected $view_data = array(); //data to be passed
public function __construct()
{
parent::__construct();
}
public function _output($output)
{
if($this->content_view !== FALSE && empty($this->content_view)) $this->content_view = $this->router->class . '/' . $this->router->method;
$yield = file_exists(APPPATH . 'views/' . $this->content_view . EXT) ? $this->load->view($this->content_view, $this->view_data, TRUE) : FALSE ;
if($this->layout_view)
{
$html = $this->load->view($this->layout_view, array('yield' => $yield), TRUE);
echo $html;
}
}
}
Application/views/layouts/layout.php
----------------------------------------------------------------------------
<html>
<head>
<title>master layout</title>
</head>
<body>
<!-- this variable yeild is important-->
<div><?=$yield;?></div>
</body>
</html>
This is what i use to create my template. Basically you need a directory structure as follows.
+Views
|+layouts
||-layout.php
the layout.php will serve as your master template
How to use?
extend the controller
class User Extends MY_Controller
{
public function create_user()
{
//code here
}
public function delete_user()
{
//use a different master template
$this->layout_view = 'second_master_layout';
}
public function show_user()
{
//pass the data to the view page
$this->view_data['users'] = $users_from_db;
}
}
Just create directory in your views and name it with the controller name i.e user then inside it add a file you named your method i.e create_user
So now your Directory structure would be
+Views
| +layouts
| |-layout.php
| |-second_master_layout.php
| +user
| |-create_user.php
Just Edit the code to give you a dynamic header or footer
Here is the simple example which i always do with my CI project.
Pass the body part as a $main variable on controller's function
function test(){
$data['main']='pages/about_us'; // this is the view file which you want to load
$data['something']='some data';// your other data which you may need on view
$this->load->view('index',$data);
}
now on the view load the $main variable
<html lang="en">
<head>
</head>
<body>
<div id="container">
<?php $this->load->view('includes/header');?>
<div id="body">
<?$this->load->view($main);?>
</div>
<?php $this->load->view('includes/footer');?>
</div>
</body>
</html>
In this way you can always use index.php for your all the functions just value of $main will be different.
Happy codeing
Using MY_Controller:
class MY_Controller extends CI_Controller {
public $template_dir;
public $header;
public $footer;
public function __construct() {
parent::__construct();
$template_dir = 'templates'; // your template directory
$header = 'header';
$footer = 'footer';
$this->template_dir = $template_dir;
$this->header = $header;
$this->footer = $footer;
}
function load_views ($main, $data = [], $include_temps = true) {
if ($include_temps = true) {
$this->load->view('$this->template_dir.'/'.$this->header);
$this->load->view($main);
$this->load->view('$this->template_dir.'/'.$this->footer);
} else {
$this->load->view($main);
}
}
}
Then load it like: $this->load_views('login_view', $data);
You can do with library.
Create a new library file called template.php and write a function called load_template. In that function, use above code.
public function load_template($view_file_name,$data_array=array()) {
$ci = &get_instatnce();
$ci->load->view("header");
$ci->load->view($view_file_name,$data_array);
$ci->> load->view("footer");
}
You have to load this library in autoload file in config folder. so you don't want to load in all controller.
You can call
$this->template->load_template("index",$data_array);
If you want to pass date to view file, then you can send via $data_array
There is an article on this topic on ellislab forums. Please take a look. It may help you.
http://ellislab.com/forums/viewthread/86991/
Alternative way: Load your header and footer views inside the concern body view file. This way you can have batter control over files you want to include in case you have multiple headers and footer files for different purposes. Sample code shown below.
<html lang="en">
<head>
</head>
<body>
<div id="container">
<?php $this->load->view('header');?>
<div id="body">
body
</div>
<?php $this->load->view('footer');?>
</div>
</body>
</html>

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