keymaster's Profile

Recent Comments

keymaster posted on 09/22/10 03:25:46 AM
keymaster posted on 09/22/10 02:33:02 AM
For situations where it is not possible to know at development time which model(s) your polymorphic model will belongTo, or for some reason you absolutely need to have a totally decoupled model codewise so it can easily associate with any model, this behavior is a great approach.

However, if at compile time you know what association(s) this polymorphic model will belongTo, and especially if you have a large number of records in your polymorphic model, you will be much better off going the standard cake route and hardcoding your associations (where possible) as a regular $belongsTo variable in the model, specifying the 'foreignKey' and 'conditions' keys in the association as appropriate to make it work.

The reason is this behavior will issue a separate db query for every record in the polymorphic model's result set (to obtain the associated model record), and then, in php, manually merge it into the results.

On the other hand, if you hardcode the $belongsTo between the polymorphic models and those it is associated with, even when it belongsTo multiple models, and you do a find on the polymorphic model, cake will fetch all the belongsTo associated data in a single join query.

For large data sets, or highly traffic'ed sites, this can have a tremendous performance difference.

Also, fyi, see: http://github.com/Theaxiom/Polymorphic2.0 for a forked enhancement of this behavior (never tried it).
keymaster posted on 03/04/08 01:46:33 PM
IF someone has been successful in getting it working in PHP4, it would be appreciated if you could post your version of the behavior.
keymaster posted on 02/27/08 06:32:41 AM
Firstly, thanks to Matt for taking the time and effort to post such a generally useful helper. I vote to include it in the cake core.

Anyways, my app uses cake 1.2's theming capability, and the asset helper as it currently exists (version 1.2 of the helper) doesn't support this. In particular, it doesn't first check the webroot/themed/ directory for the themed versions of the css/js files.

So, I made a couple of trivial modifications to the process() function in the helper.

Here it is (sorry, my comments are also included in the code - feel free to delete them).


<?php 
function process($type$data) {
    switch (
$type) {
      case 
'js':
        
$path JS;
        
$themedPath $this->webroot.$this->themeWeb.'js/';
        break;
      case 
'css':
        
$path CSS;
        
$themedPath WWW_ROOT.$this->themeWeb.'css/';
        break;
    }
    
$folder = new Folder;
    
    
//make sure the cache folder 'packed/' exists
    
if ($folder->create($path $this->cachePath"777")) {
      
trigger_error('Could not create ' $path $this->cachePath
                   
'. Please create it manually with 777 permissions'E_USER_WARNING);
    }
    
    
//Does a cached packed file exist?
    
    
$names Set::extract($data'{n}.name');
    
$folder->cd($path $this->cachePath);
    
$fileName $folder->find($this->__generateFileName($names) . '_([0-9]{10}).' $type);
    if (
$fileName) {
      
//Cached packed file exists. Take the first one...really should only be one, 
      // because we delete them, before we create another one.
      
$fileName $fileName[0];
    }
    
    
// Make sure all the components that made up the packed file
    // are OLDER then the packed version
    
    
if ($this->checkTS && $fileName) {
        
        
// Get the filetime of the packed file.
      
$packed_ts filemtime($path $this->cachePath $fileName);

      
// get the newest filetime of all the components.
      
$latest_ts 0;
      
$scripts Set::extract($data'{n}.script');
      foreach(
$scripts as $script) {
          if (
is_file($themedPath $script '.' $type)){
              
$latest_ts max($latest_tsfilemtime($themedPath $script '.' $type));
          }else{
              
$latest_ts max($latest_tsfilemtime($path $script '.' $type));
          }
      }

      
// Are any of the components newer? If so, need to rebuild the packed file, so first delete it.
      
if ($latest_ts $packed_ts) {
        
unlink($path $this->cachePath $fileName);
        
$fileName null;
      }
    }
    
    
//file didn't exist, or it did, but we deleted it because it needs to be rebuilt. Build it.
    
if (!$fileName) {
      
$ts time();

      
$scriptBuffer '';
      
$scripts Set::extract($data'{n}.script');
      foreach(
$scripts as $script) {
          
          
// first try the themed path to see if the file exists.
        
if (is_file($themedPath $script '.' $type)){
            
// file exists in themed path.
            
$buffer file_get_contents($themedPath $script '.' $type);
        }else{
            
// nothing in themed path, use the default path.
            
$buffer file_get_contents($path $script '.' $type);
        }

        switch (
$type) {
          case 
'js':
            
//jsmin only works with PHP5
            
if (PHP5) {
              
vendor('jsmin/jsmin');
              
$buffer trim(JSMin::minify($buffer));
            }
            break;

          case 
'css':
            
vendor('csstidy/class.csstidy');
            
$tidy = new csstidy();
            
$tidy->load_template($this->cssCompression);
            
$tidy->parse($buffer);
            
$buffer $tidy->print->plain();
            break;
        }

        
$scriptBuffer .= "\n/* $script.$type */\n" $buffer;
      }


      
//write the packed file to the default path. Reason we don't write to the 
      // themed path is because some of the files may have come from the theme, but some
      // may be generic to all apps and may have come from the default path.
      // So we just write the packed file containining everything to the default path.
      
$fileName $this->__generateFileName($names) . '_' $ts '.' $type;
      
$file = new File($path $this->cachePath $fileName);
      
$file->write(trim($scriptBuffer));
    }
    
    if (
$type == 'css') {
      
//$html->css doesn't check if the file already has
      //the .css extension and adds it automatically, so we need to remove it.
      
$fileName str_replace('.css'''$fileName);
    }
    
    return 
$fileName;
  }
?>