parse css with media queries and other end cases to php array - php

id like to break a css file to php array.
i have this code:
function parseCss($css_str) {
$css = array();
// TODO include external css
$css_str = preg_replace('/(#import\s+["\'].+["\'];)/', "", $css_str);
// Strip all line endings and both single and multiline comments
$css_str = preg_replace('/\s*(?!<\")\/\*+[^\*]+\*+\/(?!\")\s*/', "", $css_str);
$css_class = explode("}", $css_str);
while(list($key, $value) = each($css_class)){
$aCSSObj = explode("{", $value);
$cssSelector = strtolower(trim($aCSSObj[0]));
if($cssSelector){
// regular class not in media query
$cssprops[] = $cssSelector;
$a = explode(";", $aCSSObj[1]);
while(list($key, $val0) = each($a)){
if(trim($val0)){
$aCSSSub = explode(":", $val0);
$cAtt = strtolower(trim($aCSSSub[0]));
if(isset($aCSSSub[1])){
$aCSSItem[$cAtt] = trim($aCSSSub[1]);
}
}
}
if((isset($css[$cssSelector])) && ($css[$cssSelector])){
$aCSSItem = array_merge($css[$cssSelector], $aCSSItem);
}
$css[$cssSelector] = (isset($aCSSItem)) ? $aCSSItem : null ;
unset($aCSSItem);
}
if(strstr($cssSelector, ",") && !strstr($cssSelector, "#media")){
$aTags = explode(",", $cssSelector);
print_r($aTags);
foreach($aTags as $key0 => $value0){
$css[$value0] = $css[$cssSelector];
}
unset($css[$cssSelector]);
}
}
unset($css_str, $css_class, $aCSSSub, $aCSSItem, $aCSSObj);
return $css;
}
but that doesn't return me a css file with media queries like it supposed to be.
and if there is a ":" sign in the css value -for example an IE expression like that:
top:expression((-20+(document.documentElement.clientHeight ?document.documentElement.clientHeight/2:document.body.clientHeight/2)+(ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop:document.body.scrollTop))+'px')
its giving back cutted code.
so the result should look like that:
Array
(
[selector] => array (
[prop] => value
[prop2] => value
)
[#media handheld,only screen and (max-width:320px)] => array(
[selector] => array(
[prop] => value
[prop2] => value
)
)
)
how do i make it work?

Solved that!
eventually I've used CSSTidy to parse the css, and it does the job beautifully!
http://csstidy.sourceforge.net/index.php

Related

How to get values from comment in php

I have a comment in php file how do i get say Name: value or Type: value from the comment as in wordpress.
<?php
/*
Name: My name
Description: The description
Type: File-type
*/
?>
I tried this but could only get name can't go further.
$tokens = token_get_all(file_get_contents("filename.php"));
$comments = array();
foreach($tokens as $token) {
if($token[0] == T_COMMENT || $token[0] == T_DOC_COMMENT) {
$comments[] = $token[1];
}
}
$_to_string = trim(current($comments), "\**/");
$split_str = str_split($_to_string, stripos($_to_string, "Description"));
$explode_str = explode(":",$split_str[0]);
echo $explode_str[1];
You will need to split up the comment by lines first and then for each line try and split it by the :. If there are two components then you can use this for your data. I use the first part as the key for the output and the second as the value (remembering to trim() to clean them up)...
$_to_string = trim(current($comments), "\**/");
$out = [];
foreach ( explode(PHP_EOL, $_to_string) as $item ) {
$itemData = explode(":",$item);
if ( count($itemData) == 2 ) {
$out[trim($itemData[0])] = trim($itemData[1]);
}
}
print_r($out);
Which with your sample gives...
Array
(
[Name] => My name
[Description] => The description
[Type] => File-type
)

Insert a Variable of String into an array

I'm using a Sendinblue SMTP into my PHP project and I want to send transactionals emails to a dynamic list of emails, the problem is that I have a syntax error when I'm using a variable instead a string. For example, this code works great:
include 'Mailin.php';
$mailin = new Mailin('senders#sender.com', 'key');
$mailin->
addTo(
array(
'email1#email.com' => '', 'email2#email.com' => '', 'email3#email.com' => ''
)
)->
setFrom('sender#sender.com', 'Test')->
setReplyTo('sender#sender.com', 'Test')->
setSubject('Example')->
setText('Test')->
setHtml($htmlContent);
$res = $mailin->send();
print_r($res);
But if I use a variable instead the Strings in "addTo Array" it shows syntax error, for example:
$customers = '';
foreach ($clientes as $customer) {
for ($i=1; $i < 41; $i++) {
if ($customer['email'.$i] != "" or $customer['email'.$i] != NULL) {
$customers .= "'".$customer['email'.$i]. "' => '', " ; //for each customer's email add the email in " 'email#email.com' => '', " format
}
}
}
$customers = substr($customers, 0, -2); //removes last space and comma of the String
include 'Mailin.php';
$mailin = new Mailin('senders#sender.com', 'key');
$mailin->
addTo(
array(
$customers
)
)->
setFrom('sender#sender.com', 'Test')->
setReplyTo('sender#sender.com', 'Test')->
setSubject('Example')->
setText('Test')->
setHtml($htmlContent);
$res = $mailin->send();
print_r($res);
If I use the Print_r($customers) function it shows the exact string that I used in my first example, even if I use the code:
$text = "'email1#email.com' => '', 'email2#email.com' => '', 'email3#email.com' => ''";
if ($customers == $text) {
print_r("Yes");
}else{
print_r("No");
}
The result is "Yes", but when I use the variable in
addTo(
array(
$customers
)
)->
shows an error, but if I use the string directly the email is sent
addTo(
array(
'email1#email.com' => '', 'email2#email.com' => '', 'email3#email.com' => ''
)
)->
And I don't know why it shows error if the $customers variable has the string that is needed.
Do you know how to use the variable with the emails that I need to send?
You don't build an array by concatenating strings with => in them. To create an element in an associative array, just assign to that array index.
$customers = [];
foreach ($customers as $customer) {
for ($i = 1; $i < 41; $i++) {
if (!empty($customer["email" . $i])) {
$customers[$customer["email" . $i]] = "";
}
}
}
include 'Mailin.php';
$mailin = new Mailin('senders#sender.com', 'key');
$mailin->
addTo($customers)->
...
Also, see Why non-equality check of one variable against many values always returns true? for why you should have used && rather than || when you were skipping empty emails (which I've simplified by using !empty()).

How to parse the data obtained by using CURL to get DL?

I want to show list of journals and their abbreviation like:
Journal Name, Abbreviation
I am getting the data I need from :
http://images.webofknowledge.com/WOK46/help/WOS/D_abrvjt.html
So I am running the following:
$ch = curl_init();
//Set options
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'http://images.webofknowledge.com/WOK46/help/WOS/A_abrvjt.html'
));
$result = curl_exec($curl);
curl_close($curl);
$data=json_decode($result, true);
//!End function, make_call
But now what it shows me is the whole page, but as I said I only need the name of the journals(dt) and the abbreviation (dd). So How can I pars the result?
HTML DOM parsing via Simple HTML DOM
Scraping method ...
<?php
Function Scraper($file, $cnt = NULL) {
/*
#param $file, url or path/file
#param $cnt, (number of results to list) empty for all, or number
*/
require_once('PATH/TO/simple_html_dom.php');
//set_time_limit(0); // uncomment for large files
$result = array();
// Create DOM from URL
$html = file_get_html($file);
IF ($html) {
IF (empty($cnt)) { $cnt = count($html->find('DT')); }
foreach($html->find('DL') as $dl) {
for ($i = 0; $i < $cnt; $i++) {
$dt = $dl->find('DT', $i)->plaintext;
$dd = $dl->find('DD', $i)->plaintext;
$result[] = array(trim($dt) => trim($dd));
}
}
}
return $result;
}
$array = Scraper('http://somesite.com/page.html');
print_r($array);
?>
Example output ...
Array
(
[0] => Array
(
[D H LAWRENCE REVIEW] => D H LAWRENCE REV
)
[1] => Array
(
[D-D EXCITATIONS IN TRANSITION-METAL OXIDES] => SPRINGER TR MOD PHYS
)
[2] => Array
(
[DADOS-REVISTA DE CIENCIAS SOCIAIS] => DADOS-REV CIENC SOC
)
[3] => Array
(
[DAEDALUS] => DAEDALUS
)
[4] => Array
(
[DAEDALUS] => DAEDALUS-US
)
[5] => Array
(
[DAGHESTAN AND THE WORLD OF ISLAM] => SUOMAL TIED TOIM SAR
)
)
Updated example specific to user350082's issue ...
The definition lists DT and DD tags were not closed resulting in the dd being included in the find('dt') result.
<DT>D H LAWRENCE REVIEW<B><DD> D H LAWRENCE REV</B>
<DT>D-D EXCITATIONS IN TRANSITION-METAL OXIDES<B><DD> SPRINGER TR MOD PHYS</B>
etc. etc. etc.
Updated Function ...
Function Scraper($file, $cnt = NULL) {
/*
#param $file, url or path/file
#param $cnt, (number of results to list) empty for all, or number
*/
require_once('PATH/TO/simple_html_dom.php');
//set_time_limit(0); // uncomment for large files
$result = array();
// Create DOM from URL
$html = file_get_html($file);
IF ($html) {
foreach($html->find('DL') as $dl) {
IF (empty($cnt)) { $cnt = count($html->find('DT')); } // set count if null
for ($i = 0; $i < $cnt; $i++) {
$dd = $dl->find('DD', $i)->plaintext;
$dt = $dl->find('DT', $i)->innertext; // dt with html tags, easier for removing dd duplication
$dt = preg_replace('/\s+/', ' ',$dt); // remove extra whitespace, tabs etc.
// strip DD text duplication from DT
IF (($pos = strrpos($dt ,$dd)) !== false) {
$strlen = strlen($dd);
$dt = substr_replace($dt, "", $pos, $strlen);
}
$dt = strip_tags($dt); // remove html tags
IF (empty($dt)) { $dt = $dd; } // make sure dt is not empty
$result[] = array(trim($dt) => trim($dd));
}
}
}
return $result;
}

Create new array from existing array in php

Good Day
I have an array containing data seperated by a comma:
array (
[0]=>Jack,140101d,10
[1]=>Jack,140101a,15
[2]=>Jack,140101n,20
[3]=>Jane,141212d,20
[4]=>Jane,141212a,25
[5]=>Jane,141212n,30
)
There is a lot of data and I would like the data to be set out as:
array(
[Jack]=>
[140101]
=>[d] =>10
=>[a] =>15
=>[n] =>20
)
My code:
foreach ($out as $datavalue) {
$dat = str_getcsv($datavalue,',');
$datevalue = substr($dat[1],2,-1);
$shiftvalue = substr($dat[1],-1);
$totalvalue = $dat[2];
$sval[$shiftvalue] = $totalvalue;
$dval[$datevalue] = $sval;
$opvalue = $dat[0];
$final[$opvalue] = $dval;
}
Now it seems the array is populated even if there is no data from the original string, so my output shows results for Jack on the other dates even though there was no data for him originally. Hope this makes sense. Could anyone point out or suggest a solution please?
As mentioned in the comments, explode is what you need. See this working here.
<?php
$input = array (
0 => 'Jack,140101d,10',
1 => 'Jack,140101a,15',
2 => 'Jack,140101n,20',
3 => 'Jane,141212d,20',
4 => 'Jane,141212a,25',
5 => 'Jane,141212n,30',
);
$result = array();
foreach ($input as $key => $value) {
$valueParts = explode(',',$value); // now valueparts is an array like ('Jack','140101d','10')
$namePart = $valueParts[0];
$idPart = substr($valueParts[1],0,-1); // we need to strip the letter from the id
$charPart = substr($valueParts[1],-1); // and the id from the letter
$nrPart = $valueParts[2]; // you could use intval() to make this an integer rather than a string if you want
// Now we fill the array
if(!array_key_exists($namePart, $result)) {
$result[$namePart] = array();
}
if(!array_key_exists($idPart, $result[$namePart])) {
$result[$namePart][$idPart] = array();
}
if(!array_key_exists($charPart, $result[$namePart][$idPart])) {
$result[$namePart][$idPart][$charPart] = $nrPart;
}
}
var_dump($result);

PHP serialization error with ' " counts as two characters

I'm having problems with php serialization, when ever ' " are included i get an extra character space. Ex if it's 6 characters i get 7
$episodes_count = sizeof($episode_title);
$episodes = array();
$content = '';
for ($i = 0; $i <= $episodes_count; $i++) {
$title = htmlspecialchars($episode_title[$i], ENT_QUOTES);
$airdate = $episodes_airdates[$i];
$season = $episodes_seasons[$i];
$number = $episodes_numbers[$i];
$plot = $episodes_plot[$i];
// check if empty
if (!empty($title) && !empty($number ) && !empty($plot )) {
$episodes[] = array(
'title' => $title,
'airdate' => $airdate,
'season' => $season,
'number' => $number,
'plot' => $plot,
);
}
}
// Serialized Episodes in case they exist, if not, remove the goal post
if ( sizeof($episodes) > 0 ) {
$content = str_replace("'", '%',serialize($episodes));
}
update_post_meta($post_id, 'episodes', $content);
}
You pass some data that looks serialized to wordpress to update_post_meta - wordpress can have a problem with that and the data will get broken while stored and retrieved.
To prevent that, you can prefix the string so that it does not look serialized any longer or you even encode the whole string, e.g. with base64_encode. That will prevent wordpress and other components to modify the values due to encoding issues.

Categories