![]() |
|
Snippets |
|
Tree managed by sfPropelActAsNestedSetBehaviorPlugin plugin can be corrupted. In this case, the left & right value are not well numbered (there is hole in numbering) then some method like retrieveFirstChild() or hasChildren() can return incorrect results.
This is a method that scan all the tree and correct left & right numbering. It modify the left & right number only if necessary. It make at maximum one Select SQL request and one update SQL request by node.
It can work for any subtree of the given node or for entire tree if you give the root node as parameter. Second parameter indicate from which number, the numbering start.
public static function rebuildSubTree($base_node,$number=1) { $left=$number; $children=$base_node->getChildren(); if (is_array($children)) { foreach ($children as $child) { $number=self::rebuildSubTree($child,$number+1); } } $right=$number+1; if($base_node->getLeftValue()!=$left || $base_node->getRightValue()!=$right) { $base_node->setLeftValue($left); $base_node->setRightValue($right); $base_node->save(); } return $number+1; }
Provide 4 functions which crypt e-mail address with javascript in order to not be captured by spammers robots.
antispam_email_tag($emailaddress, $content) : generate an e-mail link_tag (mailto) encrypted in javascript
antispam_js_encrypt($content) : encrypt in javascript some text
antispam_auto_link_email_addresses($text) : Turns all email addresses into clickable links. Email links are encrypted.
antispam_email_in_html($html) : Encrypt all e-mail link in HTML
[php]
function antispam_email_tag($emailaddress, $content=null, $options = array()) { $options = _parse_attributes($options); $options['href'] = 'mailto:'.$emailaddress; if($content===null) $content=$emailaddress; return antispam_js_encrypt(content_tag('a',$content,$options),rand(-8,5)); }
[php]
function antispam_js_encrypt($content,$chr_adjust=-1) { $encoded_content=''; for ($n = 0; $n < strlen($content); $n++) { $encoded_content .= dechex(ord(substr($content,$n,1))+ $chr_adjust) ; // + $chr_adjust } $rdm_function_name = ''; while(strlen($rdm_function_name)<8) { $tmp = rand ( 65, 122); if($tmp > 96 || $tmp < 91 ) $rdm_function_name .= chr($tmp); } $js_function='function '.$rdm_function_name."(e) { for (i = 0; i <= e.length; i+=2) { document.write(String.fromCharCode((parseInt((('0x') + e.substring(i,i+2)),16)) - (".$chr_adjust.")));}}"; return "<script>".$js_function."\n".$rdm_function_name."('" .$encoded_content. "');</script>"; }
[php]
function antispam_auto_link_email_addresses($text) { $found=true; $offset=0; while($found) { $found=preg_match('/[\w\.!#\$%\-+.]+@[A-Za-z0-9\-]+\.[A-Za-z0-9\-]+/',$text,$matches, PREG_OFFSET_CAPTURE,$offset); if ($found) { $antispam_email_link=antispam_email_tag($matches[0][0]); $text=substr_replace ($text,$antispam_email_link,$matches[0][1],strlen($matches[0][0])); $offset=$matches[0][1]+strlen($antispam_email_link); } } return $text; }
[php]
function antispam_email_in_html($html) { $regex = '#<([aA])(\s)*(href|HREF)(\s)*=(\s)*[\"|\'](mailto:|MAILTO:)(.*?)[\"|\'](.*?)>(.*?)</\1>#is'; $found=true; $offset=0; while($found) { $found=preg_match($regex,$html,$matches, PREG_OFFSET_CAPTURE,$offset); if ($found) { $antispam_email_link=antispam_email_tag($matches[7][0],$matches[9][0]); $html=substr_replace ($html,$antispam_email_link,$matches[0][1],strlen($matches[0][0])); $offset=$matches[0][1]+strlen($antispam_email_link); } } return $html; }
This helper return path to a generate (and cached) thumbnail for an image and sizes given.
First it checks if the thumbnail as ever been created for the given size. If not, it created it and return the path to the thumbnail. Else, it will only return the path to the thumbnail.
Thumbnails are stored in a sub-directory of the original image named like [width]x[height].
examples : product/foobar.jpg which is 640x480 images - getThumbnail (320x320) will the first time generate the thumbnail "product/320x320/foobar.jpg", and return the path to this image.
parameters : - $image_path should be the path and filename of the image under uploads directory. ex: product/foobar.jpg - $width is the maximal thumbnail width - $height is the maximal thumbnail height
function getThumbnail($image,$width=null,$height=null, $scale = true, $inflate = true, $quality = 75) { $image_dir=dirname($image); $image_file=basename($image); $thumbnail_dir=''; if ($width>0) $thumbnail_dir.=$width; if ($height>0) $thumbnail_dir.='x'.$height; if ($width>0 || $height>0) $thumbnail_dir.='/'; if (!file_exists(sfConfig::get('sf_upload_dir').'/'.$image_dir.'/'.$thumbnail_dir.$image_file) && ($width!=null || $height!=null)) { if (!is_dir(sfConfig::get('sf_upload_dir').'/'.$image_dir.'/'.$thumbnail_dir)) { mkdir (sfConfig::get('sf_upload_dir').'/'.$image_dir.'/'.$thumbnail_dir,0777); } $thumbnail = new sfThumbnail($width, $height,$scale,$inflate,$quality); $thumbnail->loadFile(sfConfig::get('sf_upload_dir').'/'.$image_dir.'/'.$image_file); $thumbnail->save(sfConfig::get('sf_upload_dir').'/'.$image_dir.'/'.$thumbnail_dir.$image_file); } return '/uploads'.'/'.$image_dir.'/'.$thumbnail_dir.$image_file; }
This is very usefull to use it in model like this :
In model :
public function getThumbnail($width=null,$height=null) { sfLoader::loadHelpers('Thumbnail'); return getThumbnail('product/'.$this->getImage(),$width,$height); }
in template :
<?php foreach ($products as $product) { ?> <li><?php echo image_tag($product->getThumbnail(150,100)); ?></li> <?php } ?>
limitation : - work on images of upload directories only (other dir might have permission problem) - the check of thumbnail existance don't take care of scale and inflate values. It is easy to update the code to stored thumbnail in different subdirectory according to these parameters.
This is a very usefull and simple tip if you want to defined default value in edit form (only on creation of a new record) with the value that the user defined in the list filter.
An exemple for a product module which define the category select field with the value of the same field in the list filter.
action.class.php
public function executeEdit () { $filters = $this->getUser()->getAttributeHolder()->getAll('sf_admin/product/filters'); if (!$this->getRequestParameter('product_id', 0) && isset($filters['category_id'])) { $this->product = new Product(); $this->produit->setCatergoryId($filters['category_id']); } parent::executeEdit(); } protected function getProductOrCreate ($product_id = 'product_id') { if (isset($this->product)) return $this->product; else return parent::getProductOrCreate($product_id);
Here is a code for new helper functions : input_color_tag and object_input_color_tag which display a input field. When the focus is on the input a color-picker appear.
See the demo on the bottom of this webpage
2 colorpickers are available by switching the button on the right : a small and simple one, a bigger one like photoshop color picker.
To work, the colorpicker need :
You have to specify in your template or yml config file you want to use this helper php file.
Files are available here (zip files)
With admin generator you can have a field specified to be a uploading file. Then as it is written in the doc, you can wirte in your generator.yml :
picture:
name: Picture
type: admin_input_file_tag
upload_dir: picture
params: include_link=picture include_remove=true
Then the file will be uploaded in /upload/picture directory
But maybe you want to restrict the size of the picture or add different files for different picture sizes.
Then this is an easy way to generate thumbnails in subdirectories of the main upload directory specified.
Just add the following method to your action class and adapt :
action.class.php:
protected function updateProductFromRequest() { $product = $this->getRequestParameter('product'); $thumbnails[]=array('dir' => '16x16', 'width' => 16, 'height' => 16); $thumbnails[]=array('dir' => '32x32', 'width' => 32, 'height' => 32); if (!$this->getRequest()->hasErrors() && isset($produit['picture_remove'])) { foreach ($thumbnails as $thumbParam) { $currentFile = sfConfig::get('sf_upload_dir').'/picture/'.$thumbParam['dir'].'/'.$this->produit->getPhoto(); if (is_file($currentFile)) unlink($currentFile); } } parent::updateProductFromRequest(); if (!$this->getRequest()->hasErrors() && $this->getRequest()->getFileSize('product[picture]')) { $fileName=$this->product->getPicture(); foreach ($thumbnails as $thumbParam) { $thumbnail = new sfThumbnail($thumbParam['width'], $thumbParam['height'],true,false); $thumbnail->loadFile(sfConfig::get('sf_upload_dir')."/product/".$fileName); $thumbnail->save(sfConfig::get('sf_upload_dir').'/product/'.$thumbParam['dir'].'/'.$fileName, 'image/jpeg'); } } }
As for uploaded files, fenerated thumbnails are not deleted when record is deleted.
There is no method given by Symfony to redirect to module/action of an other application. Redirect method of SfActions permit only to redirect to module/action of the current application or to an url.
In the forum fabien say, it is because applications are independant.
But it could be usefull for a backend (generated with admin generator), to add a new "object_actions" which permit to view the result of a record (an article for e.g.) by redirecting to the article webpage in the frontend.
Then you can add in the Actions class an action method like :
public function executeView() { $this->redirect("http://".$this->getContext()->getRequest()->getHost().'/article/'.$this->getRequestParameter('id')); } // or if the application is not the default application (behind index.php) and the application is named "frontend" public function executeView() { $applicationName='frontend'; $this->redirect("http://".$this->getContext()->getRequest()->getHost().'/'.$applicationName.'.php/article/'.$this->getRequestParameter('id')); }
To add this action in the backend, add this line to generator.yml :
generator:
param:
list:
object_actions:
_edit: -
view: { name : View this article, action: view, icon: backend/view.png }