LESS for WordPress to compile Bootstrap 3.1+

Many of the LESS compilers for WordPress or PHP use the Leafo LessPHP library, from https://github.com/leafo/lessphp (see http://leafo.net/lessphp/docs/ ). For example, the current (6/1/2015) version of AssetsMinify plugin for WordPress uses LessPHP.

The Leafo LessPHP library doesn’t compile the LESS extend command, used heavily in Bootstrap 3.1+ and many other LESS packages. “Extend is a Less pseudo-class which merges the selector it is put on with ones that match what it references.” And it seems Leafo LessPHP isn’t getting updated.

Even worse, many libraries haven’t modified the Leafo package to even catch the failure — they fail with a PHP fatal error such as PHP Fatal error: Uncaught exception 'Exception' with message 'parse error: failed at `&:extend(.clearfix all);`. At a minimum, the library should catch the exception, so that PHP doesn’t abort; the exception should leave a comment in the generated CSS such as “This version of LessPHP uses a version of Less that does not support this code: <code>&:extend(.clearfix all);</code>”.

If you use the Leafo LessPHP library and it produces a PHP fatal error in WordPress, you will probably get a “white screen”. If you know how to turn on WordPress and PHP debugging information you can see that uncaught exception in your error logs, and at least know your LESS file having an unsupported command was what brought your site down.

How do you get around this? One way is to simply use LESS without the ‘extend’. But the LESS extend command has been around for years now. The Bootstrap release log shows v3.1.0 released on Jan 30, 2014 had “With switch to LESS compiler, remove duplicate CSS generated from the nested .clearfix class and mixin by switching to &:extend(.clearfix all).” The Extend command has a lot of benefits.

As of 6/1/2015, Bootstrap is currently v3.3.4 and there are many improvements over version 3.0. Good thing there are ways to use Bootstrap 3.3.4 .less files with WordPress.

https://github.com/oyejorge/less.php is a different Less compiler for PHP. I haven’t compared the main package yet. But reading about it, I saw it has a section on replacing the leafo lessc.inc.php with oyejorge lessc.inc.php. You copy lessc.inc.php and the lib/ folder from oyejorge’s less.php-master.zip into a folder (I used the folder in my WordPress theme with my .less files, /wp-content/themes/THEMENAME/less)

I’m able to generate a custom version of Bootstrap 3.3.4, incorporating my own changes (.less files that calculate a “color wheel” to produce background colors that look great with a main color I select, and making text colors that have good contrast against their background color, and applying those colors throughout Bootstrap.

I have my main file, style.less, include all the other .less files; these are all in /wp-content/themes/THEMENAME/less
Example: @import "scheme.less";
@import "bootstrap/bootstrap.less";
@import "my-bootstrap-variables.less";
@import "my-mixins.less";

The oyejorge version of lessc.inc.php is also in /wp-content/themes/THEMENAME/less
The oyejorge lib/ folder and all the files in it are in /wp-content/themes/THEMENAME/less (making /wp-content/themes/THEMENAME/less/lib/)
The Bootstrap Less files are in /wp-content/themes/THEMENAME/less/bootstrap

(Since Less definitions found afterwards overwrite definitions found before, and only then are applied in functions and mixins, I have my-bootstrap-variables.less and my-mixins.less after the import for Bootstrap, and all the colors generated in scheme.less get put into Bootstrap goodies.)

Here is the code I have in my functions.php (in /wp-content/themes/THEMENAME/) :
require "less/lessc.inc.php";
$less = new lessc;
try {
/* works, but autoCompileLess is better -- $less->compileFile(__DIR__."/less/style.less", "/style.css"); */
autoCompileLess(__DIR__."/less/style.less", __DIR__.'/style.css');
} catch (exception $e) {
echo '

Error making CSS files: ' . $e->getMessage() .'

';
}

Here is the autoCompileLess function, also goes in functions.php:

/* from http://leafo.net/lessphp/docs/#compiling_automatically
*/
function autoCompileLess($inputFile, $outputFile) {
// load the cache
$cacheFile = $inputFile.".cache";

if (file_exists($cacheFile)) {
$cache = unserialize(file_get_contents($cacheFile));
} else {
$cache = $inputFile;
}

$less = new lessc;
$newCache = $less->cachedCompile($cache);

if (!is_array($cache) || $newCache["updated"] > $cache["updated"]) {
file_put_contents($cacheFile, serialize($newCache));
file_put_contents($outputFile, $newCache['compiled']);
}
}

Delicious Desserts and Breads, Diabetes Healthy

Thanks to a new breed of healthy natural sweeteners, low glycemic flours, and slimming fats (yes, you read that right!), you can whip up delicious treats and breads that pack serious nutrition and burn fat too!

These books give recipes that have the taste and texture of breads and desserts we love, but without the health costs.

Guilt-free desserts, delicious and healthy for diabetics

Divinely delicious desserts with all-natural, low glycemic ingredients, without the sugar (but with healthy sweeteners that don’t spike blood sugar), easy to make and very nutritious.

Better breads, low glycemic, delicious

Breads that are low glycemic, gluten free, no grain, low starch, heart healthy (lacking the specific type of LDL cholesterol that is the main risk factor for heart disease, yet wheat is full of), and weight improving.

Gluten-free breads with the texture we love, and very healthy.

Creating REAL Bread with Good-for-You Ingredients. The goal was to create breads so good they could be served in a restaurant.

No complicated techniques… no fancy equipment (not even a bread machine)… and no need to knead. fat-burning brownies, gluten free

All these delicious foods had to be made with inexpensive real-food ingredients. They would contain NO grains or gluten. And the final product had to be low-glycemic – no blood sugar spikes.

And that’s not all… they would only be satisfied if the recipes were fast and easy to make.

Guilt-Free Desserts: 50 All-Natural, Gluten-Free, Fail-Proof, Low-Glycemic Desserts
Plus:
Better Breads – A Dozen Quick & Delicious, Gluten Free, Low Glycemic, Breads, Biscuits, Crepes & Crusts
and:
Awesome Appetizers – Tips, Sips & Healthy Hor d’Oeuvres Perfect for any Occasion

Go let your eyes check out how good they look, and your mouth will begin wanting them!

http://glerner.com/recommends/gfdesserts

BackWPup – Trying to get property of non-object

BackWPup version 3.1.2 – error message with Debugging mode on “Trying to get property of non-object”

in class-job.php
in public static function get_jobrun_url( $starttype, $jobid = 0 )

Change

$wp_admin_user = get_users( array( ‘role’ => ‘administrator’, ‘number’ => 1 ) ); //get a user for cookie auth

to

$wp_admin_user = get_users( array( ‘role’ => ‘backwpup_admin’, ‘number’ => 1) ); //get a user for cookie auth

(probably better to test for either? On my system, only one Administrator, but the role is set to backwpup_admin, there are None with ‘administrator’)

BackWPup uses (or at some earlier time used?) a different Role for the backup administrator, ‘backwpup_admin’ instead of the default Role ‘administrator’.

This is on BackWPup version 3.1.2 on WordPress 3.9.2

Hard Coded Links in Theme File Causing Error

The Theme Check plugin checks for errors in your design or coding of WordPress themes.

If you are getting “INFO: Possible hard-coded links were found”, that literally means you have hard-coded links, you typed the URL in. Proper links should have been “escaped”, or passed through a function to make sure they contain only characters that are valid in URLs. If the URL is used in multiple places, you also should consider putting the URL in a PHP variable so if you need to change it, you change it in only one place.

http://codex.wordpress.org/Theme_Development
“Untrusted Data
“You should escape dynamically generated content in your Theme, especially content that is output to HTML attributes. As noted in WordPress Coding Standards, text that goes into attributes should be run through esc_attr() so that single or double quotes do not end the attribute value and invalidate the XHTML and cause a security issue. Common places to check are title, alt, and value attributes.” Continue reading Hard Coded Links in Theme File Causing Error

Tracking Down Deprecated Functions

You may be seeing warnings like this if you have WordPress Debug mode enabled:

“Notice: wpdb::escape is deprecated since version 3.6! Use wpdb::prepare() or esc_sql() instead. in /home/USERNAME/public_html/wp-includes/functions.php on line 2913″

I am getting this with WordPress version 3.8.1, and the Domain Mapping plugin wordpress-mu-domain-mapping version 0.5.4.3 but “deprecated” messages happen with many, many plugins.

The wp-includes/functions.php is a WordPress core file. The function at the line mentioned is reporting the error, not the line with the error. To fix the error, you need to know where the error originates. I’m going to show you how to find that. Continue reading Tracking Down Deprecated Functions

Oatmeal Cookies, No Wheat

4 cups Rolled Oats
3/4 cup Canola Oil (more omega-3 and less allergens than corn or soy oil)
1/3 cup Honey (raw, unfiltered, more nutrients and more flavor)
Mix and let stand 8 hours

1 tsp vanilla extract
4 tsp ground cinnamon

If you want cookie shape instead of oatmeal crumble:
2 eggs, well beaten
1/2 tsp salt (dissolve in eggs, or get salty bites)

Add to taste:
raisins
chocolate chips or
1 tbsp chocolate powder (natural and Dutch processed, no added sugar)
raw almonds or walnuts, finely chopped

Preheat oven to 350F
Lightly coat baking sheet with butter, or natural cooking spray
Spoon mixture onto sheet (about 1/2 inch thick; if making cookies, about 2 dozen)

Crispy: bake 17 minutes, store in a non-airtight container

Moist: bake 14 minutes, store in airtight container

Original recipe (“Awake Oatmeal Cookies”) was much sweeter. 2 cups brown sugar instead of honey, 1 cup oil (use less oil when use honey).

Security from Bad User Agents

One way to protect your site is blocking bad “User Agents”.

A user agent is the way your browser identifies itself to your server. Your server could use this to send different versions of your site to the browser; for example, not sending images to a Lynx browser that only displays text, or to a browser that is a screen reader for blind or low-vision people. My Firefox browser has this user agent:

Mozilla/5.0 (Windows NT 6.1; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0

Search engines also make requests of your server and identify themselves with a user agent, as do hacker bots.

The User Agent can be changed. Some browsers pretend to be a version of Internet Explorer. Some hacker bots pretend to be any major browser they like, switching for different requests. Some pretend to be Google’s search engine bot.

Web site developers will use browser plugins to send a different user agent string, so they can test what their web site sends to people with other browsers. (I’m using the Firefox “User Agent Overrider” plugin to change my browser’s user agent; on my server I detect user agent, which lets me know the browser type and version, operating system, whether it is a mobile device, and more, using a PHP script from http://techpatterns.com/downloads/php_browser_detection.php which I think is much nicer than using javascript since I only send to the browser the best HTML/ CSS for it.

So the User Agent isn’t a good field to check for security. There are other fields that bad bots can’t fake, for example bad words/phrases in the URL they are looking for on your site.

But checking the user agent is good for blocking nuisances that waste your site resources.

How Do You Block a User Agent

Almost all shared hosting accounts are on Apache servers.  Microsoft IIS is much harder for most people to use, so I’ll give Apache .htaccess examples.

The “Better WP Security” plugin for WordPress has a good-sized list of bad User Agents that it can add to your site’s list.

Here’s some of their code for blocking user agents (all the other examples I’ve seen use the exact same approach):

RewriteCond %{HTTP_USER_AGENT} ^EirGrabber [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^EmailCollector [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^EmailSiphon [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^EmailWolf [NC,OR]

The ^ means “at the start” of the User Agent, the [NC,OR] says not case sensitive and any one or the other will match.

Here’s how I do the same thing, but allowing me to set exceptions to the security rule, and to log what specifically triggered the rule:

SetEnvIfNoCase User-Agent (eirgrabber|emailcollector|emailsiphon|emailwolf) badUserAgent=$1

For User-Agent values that have multiple values (the | separates them) and that contain special characters, you must use substitutions:
\s for spaces, \. for period, @ : ! are permitted
For this User-Agent: Bot mailto:craftbot@yahoo.com use this in your .htaccess: Bot\smailto:craftbot@yahoo\.com

Then I send bad user agent requests to a page this way:

RewriteCond %{REQUEST_URI} !/shared/bad-webbot.php$ [NC]
RewriteCond %{REQUEST_URI} !/shared/403.php$ [NC]
RewriteRule (.*) /shared/bad-webbot\.php [E=badUserAgent:%0,L]

First I check that the file being requested isn’t one of  my “error” pages. The user agent doesn’t change when I redirect to an error page, so if I don’t make an exception for my error page, the server has a security conflict (you told me to display this page with that security rule, but the page violates the security rule) and gives up by showing a bare “500: Server Error”.  Then I redirect the requested file to my “you’re a nuisance” page.

The E=badUserAgent:%0 sets an environment variable that my bad-webbot.php page can read.

The ,L says this is the Last thing to check in .htaccess, go right to the page.

My bad-webbot.php just displays minimal HTML, with no style sheet. But it also logs the IP address and what makes me think they’re a nuisance, in this case which phrase in their user agent triggered the security script. If something is being blocked incorrectly, I can see it in the log.

One exception I found for user agents was for LinkedIn. “Jakarta” is one of the agents suggested for blocking, but LinkedIn uses this user agent. Another I made an exception for is Alexa.

LinkedInBot/1.0 (compatible; Mozilla/5.0; Jakarta Commons-HttpClient/3.1 +http://www.linkedin.com)

Here’s how I made the exceptions:

SetEnvIfNoCase User-Agent ia_archiver\ \(+http://www\.alexa\.com\/site\/help\/webmasters;\ crawler@alexa\.com) !badUserAgent
SetEnvIfNoCase User-Agent LinkedInBot/1\.0\ \(compatible;\ Mozilla/5\.0;\ Jakarta\ Commons-HttpClient/3\.1\ +http://www\.linkedin\.com) !badUserAgent

Notice how I put a backslash before all spaces, periods and slashes inside the user agent string.

The ! before the variable (badUserAgent) un-sets the environment variable.

Don’t Use HideMyWP

Quick look: HideMyWp changes the URLs (“Change WordPress permalinks” and the URLs for plugins and administrative pages). Whoop-tee-doo.

Hackers getting in from server-level security breaches don’t use a URL, they are already inside the security system.

Hackers from bad plugins know the internal location they are run from (a necessary PHP function), and easily get the location of all other plugins, with a single database query; they’re already inside the security system.

HideMyWP thinks that’s “good security”. The site says, “This means you can install unsafe plugins without worry about security.” — they are lying or incompetent. An unsafe plugin can change the content of your post/pages/comments, ruin your database, install malware, collect your user names and passwords, send out emails, etc. Continue reading Don’t Use HideMyWP

Checking if Plugins Pass Basic “Good Programming” Test

On http://wordpress.org/ideas/topic/plugins-and-theme-repository-thorough-bug-update-and-security-review/ there is discussion about adding to WordPress a “system of testing and making sure that plugins and themes work, are up to date (no plugins over a year old, say) and are bulletproof secure. The plugin and theme repository should demand that every single plugin and theme should be rigorously reviewed and screened for security.”

My suggestions for a Partial solution, that could Easily be checked for by the Plugin repository and by the WordPress Core:

1) /wp-admin/network/plugins.php shows if are using the latest version of each plugin. But it doesn’t indicate the Date of the latest version, or if the latest version date is a long time ago. Adding the date would be extremely easy.

2) On plugins.php display the version of WordPress the plugin was written for, just like the plugin repository page does. Display the user rating from the repository, for your installed version of WordPress with your installed version of the plugin.

3) Plugin repository could list results of installing the plugin in a default configuration, with full error reporting on, testing for a) syntax errors, b) obsolete function calls, c) database errors, d) direct MySQL calls (e.g. bypassing WordPress security and roles), e) multi-site initialization errors (e.g. are tables created for the plugin when create a site? Does the plugin put data in wp_options or in wp_SITEID_options? ).

The test site would be restored to default state after each plugin test. The test would be run at each plugin update posted to the repository. This sounds like something that could be easily automated.

Not a guaranteed security or quality test, but a good check of the basics.

@Ipstenu replied “We have yet to manage to do it in a way that didn’t net a bajillion false positives that we have to look at them all manually anyway :/ ”

Nope. Purely objective reports.

Have PHP error logging set to maximum, use software to count each category of error, report the findings. Already includes obsolete WordPress functions, obsolete PHP functions, syntax errors, mismatched variable types, uninitialized variables, and more.

Look for occurrences of the most common MySQL function calls (instead of WordPress database functions), report the number.

Get a list of tables after adding a new site (single MySQL query). Software subtract the list of tables started with. Report the difference (or maybe a little more secure, the # tables).

Another test: Any plugin using wp_ instead of the actual table prefix, isn’t programmed well.

Similarly, # rows in [tableprefix]_options before and after (shouldn’t change, plugins should use [tableprefix]_[siteid]_options).

Show the whole list in a new tab in the Repository, for each version, and watch plugin authors clean up their act!

Check Plugins are Multi-Site Compatible

As a WordPress Multi-Site administrator, make sure a plugin works with multi-site before installing it. Plugin authors should state if the plugin works with multi-site.

Testing is best done on a separate installation of WordPress (the one good reason for having multiple WordPress installations), so if there is a problem it doesn’t affect your production site.

Plugin Authors: If you have tested the plugin with multi-site, then claim the feature in your marketing. I would not use a plugin that doesn’t say it works on multi-site, since even though I am technically qualified to do that testing it is much too much work to have to do.

Does the plugin always request the table prefix from WP? (One immediate clue is a plugin that uses ‘wp_’, the default, even though that isn’t what you used when installing WordPress; then WordPress appends the site ID to that prefix for all user data.)

Does the plugin always request the folder locations from WP? In multi-site mode, each site gets a unique file upload location.

Does each site of the multi-site get its own set of plugin tables, for plugin options and for user data?

When a plugin is activated on an existing site, are tables checked for, and created if needed? (Or do thousands of error messages about missing tables clutter the error log? Yuck!)

When the plugin is network activated, and a new site is created, does the plugin activation work? Is there a reminder in administration panels, to configure the plugin for the site?

When a site is deleted, does the plugin deactivation work?

If the plugin creates file (for example, a podcast creating plugin would have the podcast episodes listed in a .xml file), does each site get a separate result file, or separate collection of files?

Improper multi-site use would assume the table prefix, or assume the folder locations, or use one set of plugin tables for all users, or use one folder for all user’s media files, or allow unauthorized people to include in their post or results some information from other users, or allow unauthorized people to modify someone else’s tables or files.

Plugin Author: State in the installation instructions or FAQ whether the plugin is safe to use in a multi-site installation. State whether the plugin can be network activated or must be activated on each site. State in the change log when multi-site features are added or fixed.

Configuring XAMPP for Multiple Web Sites

To use XAMPP for developing multiple web sites, specify a ‘host name’ for each web site to use. Each web site will have its own folder on your computer. Link a host name, to a folder with your web site files. Edit the web site files, view them on your web browser (skipping the normal FTP step for each change); when the page is working, publish it to the Internet.

You can define your own host names. Some people use .local for their naming convention (http://www.yourdomain.com on the Internet, http://www.yourdomain.local on your development computer). Or use local.yourdomain.com, which should be looked for on your computer before on the Internet. I like a simpler one, since I’m doing it only for me: yd.c (Yes, you can name it anything you want, on your own computer only). Two or three letter abbreviation, and .c, you’d be amazed how typing 4 characters instead of a long domain name, again and again, matters in developing and testing a web site.

You define “your own host name” in two places, one for XAMPP, one for Windows. Continue reading Configuring XAMPP for Multiple Web Sites