Zend_Validate_StringEquals
Jan0
If you ever wonder where that 'StringEquals' validator rule taken as example from the Zend_Filter_Input documentation page results in an error like below, well read again. It was clearly stated as 'hypothetical'.
Plugin by name 'StringEquals' was not found in the registry; used paths: Zend_Validate_: Zend/Validate/
Given such validator would be useful on a number of situations i.e. confirming passwords, emails, etc. I present to you my own version of the class.
<?php class Zend_Validate_StringEquals extends Zend_Validate_Abstract { const NOT_EQUAL = 'stringNotEqual'; const MISSING = 'stringMissing'; /** * @var array */ self::NOT_EQUAL => "%field1% and %field2% are not equal.", self::MISSING => "One or both strings are missing." ); /** * @var array */ 'field1' => '_field1', 'field2' => '_field2' ); protected $_case = false; protected $_field1 = null; protected $_field2 = null; /** * Sets validator options * * @param boolean $case * @return void */ public function __construct($case = false) { $this->_case = $case; } /** * Defined by Zend_Validate_Interface * * Returns true if and only if the the 2 strings are equal * * @param array $value * @return boolean */ public function isValid($value) { $this->_error(self::MISSING); } if($this->_case === true) $function = 'strcmp'; else $function = 'strcasecmp'; if(0 !== $function($this->_field1,$this->_field2)) $this->_error(self::NOT_EQUAL); return false; } else { return true; } } }
Here is a sample test case. Validate password and confirm password elements represented by 'password' and 'cpassword' element names respectively.
'presence' => 'required', 'fields' => 'password', 'messages' => "Passwords must be between 5 and 15 characters in length."), Zend_Validate_StringEquals::NOT_EQUAL => "Passwords does not match.", Zend_Validate_StringEquals::MISSING => "Both password fields must be filled.")))); $inputdata = new Zend_Filter_Input($filter,$validators,$_POST,$options);
FFMpeg-PHP: undefined symbol: php_gd_gdImageSetPixel
Oct4
I was recently updating ffmpeg-php on one of our servers to the latest SVN release of the 0.6.3 branch. On a 64bit CentOS 5.3 with PHP 5.2.11, the extension compiled and installed fine however Apache will not load it and spit out the error below:
PHP Warning: PHP Startup: Unable to load dynamic library '/usr/lib64/php/modules/ffmpeg.so' - /usr/lib64/php/modules/ffmpeg.so: undefined symbol: php_gd_gdImageSetPixel in Unknown on line 0
Surely enough, the GD extension was there, but why is ffmpeg complaining about not finding that shared symbol? Because, ffmpeg is loading first than GD (alphabetically) and such symbol has not been loaded. After adding the GD extension line on top of ffmpeg making sure it loads first the error went away and all is well again.
Do you favor a “LAMP (Linux, Apache, PHP, MySQL) Integrator”?
Aug0
I have been reading on a number of project management articles lately and trends on open source projects. There seems to be a lot of fellow PHP developers who are as well Linux administrators for many server functions inluding HTTP servers like Apache and database administrators like for MySQL. Many of them are certified for one or more while many are jumping between careers that emphasizes one to the other thus gaining essential experiences for each.
Looking at job posts from all over the internet, you should've noticed at one time a PHP gig that requires MySQL administration skills and/or knows their way around Linux. PHP does not come by itself anymore, at least commonly, thus I've thought the term "LAMP Integrator". A quick Google search does not seem to turn much on how to define such, thus I have a simple one.
LAMP Integrator - is a PHP developer primarily using MySQL as data backend with strong Linux administration and Apache tuning skills.
It may sound primitive, I am writing as I am thinking so comments and revisions are welcome.
Gumblar .cn – Infiltrating Hosting Accounts
May0
Hosting accounts being compromised has been a common incident, however a sudden surge of this variant is quite alarming. This trojan does not target any particular software or script and is commonly exploited from a users computer where he usually FTP files to hosting accounts. The trojan scans for FTP usernames and passwords and use them to inject PHP scripts to the FTP server.
So far I have seen two variations, one being a slave for XSS attack and another as proxy or zombie perhaps for a DoS attack.
What to do or how do you know if you are infected? There is no simple prevention measure I can offer aside from asking you to scan and thoroughly clean your computer first. Download all your files from the ftp server, you can do PHP files only, however there is a probability a JS based file may exist as well. After downloading, scan all your files and reupload. Not too neat but it's the only method that works for me.
Cloak PHP Files as Directories and Force Trailing Slash via mod_rewrite
May0
In an effort to turn a client's website to be more SEO friendly, they wanted to have all PHP files appear as directories on URLs i.e. http://dotmanila.com/blog/php-cloak-and-force-traling-slash.php will end up as http://dotmanila.com/blog/php-cloak-and-force-traling-slash/. We've thought of creating a simple controller combined with mod_rewrite to handle this change on their 30+ websites, however it'll be inefficient to use a two-fold process. So we toyed with mod_rewrite and came up below.
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
# These first set of rules makes sure that visitors
# are viewing the WWW domain i.e. www.dotmanila.com
Rewritecond %{HTTP_HOST} !^www\.dotmanila\.com
RewriteRule (.*) http://www.dotmanila.com/$1/ [R=301,L]
# The next set of rules checks that if the URL
# does not have a trailing slash and
# the requested file/directory when appended
# with the .php extension physically exist on the server
# the we will append a traling slash
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ http://www.dotmanila.com/$1/ [L,R=301]
# The last set of rules makes sure that if
# the requested URL is in proper format the
# corresponding PHP file is mapped.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)/$ /$1.php [NS,L]
Cheers!
Fetch Smarty Templates From MySQL Database
Mar0
I was recently working on a mailing application. With the nature of the bulk mailing routine, it was designed to store templates made by its users and email designers. Since most of them have been exposed to Smarty templating before we decided to base our email template parsing to Smarty.
Smarty does not come with the ability to parse templates from database natively, but it is easy to extend it to do just that.
DISCLAIMER: This is a quick and dirty hack I provided with my colleagues. Improvement required!
This approach should work on both PHP 4 and PHP 5, since Smarty.class.php is written on PHP 4.
What we will need to do is extend Smarty.class.php on a new class and override function _fetch_resource_info and replace the if clause demonstrated below to use our code that actually fetches database stored templates.
class Smarty
{
function _fetch_resource_info(&$params) {
....
if ($this->_parse_resource_name($_params)) {
.....
}
....
}
}
Our resulting class would look something like:
require_once 'Smarty.class.php';
class Smarty_Db extends Smarty
{
function _fetch_resource_info(&$params) {
....
$_resource_type = $_params['resource_type'];
$_resource_name = $_params['resource_name'];
$db = new Template_Db;
if ($params['get_source']) {
$params['source_content'] = $db->fetchTemplate($myTemplateId);
}
$params['resource_timestamp'] = now();
$_return = true;
....
}
}
So you would then use your Smarty extended class like:
$smarty = new Smarty_Db; $smarty->compile_dir = '/path/to/my/compile/dir'; $compiledTemplateFromDb = $smarty->fetch($myTemplateId);
That is all there is to it actually. I haven't went through all the Smarty pre and post processing, but this should suffice the requirements for now.
Hope this helps.
Image Resize with PHP and ImageMagick Maintaining Proportions
Feb1
There are many examples found on the web on resizing images using PHP while maintaining aspect ratio. However most of them are based on a single maximum dimension i.e. should not exceed a certain size with on either height or width.
I have written the code below that will accept a desired height and width and downsize the source image without exceeding either $maxheight or $maxwidth but still maintain proportions.
Adjust your path to ImageMagick accordingly (/usr/bin/convert)
function resizeimage($source,$dest,
$maxwidth = 200,$maxheight = 160)
{
list($width,$height) = getimagesize($source);
/**
* We need to get both ratios so we can
* find which reduced height and width
* will fix the max allowed dimensions.
*/
$hRatio = $maxheight / $height;
$wRatio = $maxwidth / $width;
/**
* Test Dimensions based on height reduction ratio.
*/
$tHeightHR = $maxheight;
$tWidthHR = ceil($hRatio * $width);
/**
* Test dimenstions based on width reduction ratio.
*/
$tWidthWR = $maxwidth;
$tHeightWR = ceil($wRatio * $height);
if($width < $maxwidth AND $height < $maxheight)
{
echo 'Source already below maximum dimensions: '
. $source . " {$width}x{$height}\n";
return false;
}
if($tWidthHR <= $maxwidth) {
$height = $tHeightHR; $width = $tWidthHR;
}
if($tHeightWR <= $maxheight) {
$height = $tHeightWR; $width = $tWidthWR;
}
$cmd = "/usr/bin/convert -resize {$width}x{$height} "
. "\"{$source}\" \"{$dest}\" 2>&1";
@exec($cmd,$output,$retvar);
if($retvar != 0)
{
echo implode(" -- ",$output);
return false;
}
return true;
}
Face Detection with PHP
Jan2
I was enjoying playing photofunia.com a while ago when I got interested on how I can implement such a thing with opensource tools, specifically LAMP. In less than a minute, with "php face detection" on Google I found this.
The headline does say face detection - but what does this mean? Easy said, this article focus on how to find faces on images with PHP. Faces have a certain form and so it is possible to search for it. At the end of the search you will say how many human faces are on the image or better: Where are human faces on my image. This article is not intended to be mathematically.
Intel works on the OpenCV library to search for structures on images. The library is shipped with training files, what was trained with hundrets of photos to detect faces from different perspectives on images and so we can focus on the PHP part.
CodeIgniter and Smarty
Jul0
I've been used to working on projects using Smarty, its flexibility and most of the HTML designers and graphics artists I have worked with are only familiar with it. Until recently I was compelled by my co-worker to use a framework and he started using CodeIgniter without our prior approval and knowledge. To save time, I have to deal with it and continue with the CI path. Fortunately, CI can be simply extended from its Models, Controllers, libraries even its core files so it was not a big deal tying Smarty and CI together. This is how we do it.
According to the CI User Guide -> Creating Libraries, you can create your own library or extend/replace an existing native CI library. So far we need to create our own and extend from Smarty. SO in our application folder we add our Smarty library like shown in the folder structure below:
+/system
|
+----/application
|
+----/libraries
|
+----/smarty
| |
| +----/internals
| +----/plugins
| +----/Config_File.class.php
| +----/debug.tpl
| +----/Smarty.class.php
| +----/Smarty_Compile.class.php
+----/JHSmarty.php
+----/JHController.php
The above tree is only the part we are concerned, tying up Smarty with CI using libraries. You will notice two additional files, JHSmarty.php and JHController.php. Let us deal with JHSmarty.php first.
JHSmarty.php will serve as you CI custom library, it will extend the original Smarty class and we will add some additional functions for more flexibility. Consider the following example JHSmarty.php file.
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
require_once "smarty/Smarty.class.php";
class JHSmarty extends Smarty
{
public $CI = null;
public function __construct()
{
parent::Smarty();
}
public function view($resource_name, $cache_id = null) {
if (strpos($resource_name, '.') === false) {
$resource_name .= '.tpl';
}
return parent::display($resource_name, $cache_id);
}
public public function register_ci()
{
$this->CI =& get_instance();
}
}
?>
Now to breakdown each component:
__construct : As any PHP class we need a constructor, in this case we as well initialize our parent class by calling parent::Smarty();.
view : This is a simple implementation of the Smarty::display() function wherein we can optinally pass only the name part of a template file without the ".tpl" extension. This can be useful if you are presenting static pages self contained on a template.
register_ci : This function registers an instance of the CI base object into Smarty, meaning including all methods, variables and objects that you will normally find in your controller. Except in this case when you call the function the CI instance will be available as i.e. $this->CI->load->model('Somemodel','somemodel');. This is very useful if you are adding custom modifiers, plugins, etc to Smarty and you want to tap into existing resources in the CI object. Since smarty will pass itself to any plugin, modifier or outputfilter you can access it like this from any of them:
$smarty->CI->load->model('Somemodel','somemodel');
Also, you might want to autoload you JHSmarty library as you will be using your templating engine all through out your project. To automatically load your library just add the class name in all lowercase to your /system/application/config/autoload.php
$autoload['libraries'] = array('jhsmarty');
So in your controller you can always reference your custom library as:
$this->jhsmarty
Now, let's go to the next file, JHController.php. The file is an extension of the native Controller class that comes with CI. Why would I need one? Simply because I need to control some aspects of my site on the Controller level i.e. Auth checking, loading global variables, etc.
One important note is, the JH prefix on the controller name (JH on the smarty library does not count I just used it for consistency). You must define your subclass prefix for CI to use them, /system/application/config/config.php contains the relative configuration.
$config['subclass_prefix'] = 'JH';
So what do I have on my extended Controller:
The defaultview variable : Since my extended native controller will be used on all further controllers within my project, I can use this variable to assign the template I will be using to display the current request.
The finalize method : This method will serve as my Smarty::display() version except that I can assign as much variables and control the further display of the defaultview variable. I can also trap errors and display an error page if needed.
I hope you find this article useful, mainly I wrote this for a new programmer I am working with. If you have any questions/comments feel free to drop a comment below.












