Location: PHPKode > projects > phTagr > phtagr/Model/Behavior/RelatedBehavior.php
<?php
/**
 * PHP versions 5
 *
 * phTagr : Tag, Browse, and Share Your Photos.
 * Copyright 2006-2012, Sebastian Felis (hide@address.com)
 *
 * Licensed under The GPL-2.0 License
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright     Copyright 2006-2012, Sebastian Felis (hide@address.com)
 * @link          http://www.phtagr.org phTagr
 * @package       Phtagr
 * @since         phTagr 2.2b3
 * @license       GPL-2.0 (http://www.opensource.org/licenses/GPL-2.0)
 */

class RelatedBehavior extends ModelBehavior 
{
  var $config = array();

  /** Config the behavior
    @param Model Current model reference.
    @param config Configuration for the related results
    - relatedHabtm: Related HasAndBelongsToMany model. Default is the first HABTM model
    - fields: Array of fields of the model which should be fetched
    - limit: Limit count of the related items. Default is 16 */
  function setup(&$Model, $config = array()) {
    $default = array();
    if (isset($Model->hasAndBelongsToMany) && is_array($Model->hasAndBelongsToMany)) {
      foreach($Model->hasAndBelongsToMany as $key => $definitions) {
        if (is_string($key)) {
          $default['relatedHabtm'] = $key;
          break;
        } elseif (is_string($definitions)) {
          $default['relatedHabtm'] = $definitions;
          break;
        }
      }
    }
    $default['fields'] = array($Model->primaryKey);
    foreach($Model->_schema as $name => $definitions) {
      if (in_array($definitions['type'], array('string', 'text'))) {
        $default['fields'][] = $name;
      }
    }
    $default['limit'] = 16;

    $this->config[$Model->name] = am($default, $config);
  }

  /** Search for related items
   *
   * <code>
   * $tag = $this->Media->Tag->findByName($name);
   * $this->Media->Tag->Behaviors->attach('Related', array('relatedHabtm' => 'Media', 'fields' => array('id', 'name')));
   * $this->Media->Tag->bindModel(array('hasAndBelongsToMany' => array('Media')));
   * $this->data = $this->Media->Tag->related($tag['Tag']['id']);
   * </code>
   * 
   * @param Model Reference to the current model (Set automatic by the Behavior)
   * @param ids Id or Array of Ids to be related to
   * @param options Options
   * - relatedHabtm: (Optional) Related HasAndBelongsToMany model
   * - fields: (Optional) Array of fields of the model
   * - limit: (Optional) Limit count of the related items */
  function related(&$Model, $ids, $options = array()) {
    $ids = (array)$ids;
    if (count($ids) == 0) {
      return false;
    }

    $config = am($this->config[$Model->name], $options);
    $relatedHabtm = $config['relatedHabtm'];
    if (!isset($Model->hasAndBelongsToMany[$relatedHabtm])) {
      return false;
    }
    $prefix = $Model->tablePrefix;
    $table = $Model->table;
    $alias = $Model->alias;
    $key = $Model->primaryKey;
    $count = 'Count';

    $joinTable = $Model->hasAndBelongsToMany[$relatedHabtm]['joinTable'];
    $joinAlias = $Model->hasAndBelongsToMany[$relatedHabtm]['with'];
    $associationForeignKey = $Model->hasAndBelongsToMany[$relatedHabtm]['associationForeignKey'];
    $foreignKey = $Model->hasAndBelongsToMany[$relatedHabtm]['foreignKey'];

    $sqlFields = array("COUNT(*) AS $count");
    foreach((array)$config['fields'] as $field) {
      $sqlFields[] = $alias . '.' . $field;
    }

    $sql =  "SELECT " . implode(', ', $sqlFields) . " ";
    $sql .= "FROM $prefix$joinTable AS $joinAlias ";
    $sql .= "JOIN $prefix$table AS $alias ON $joinAlias.$foreignKey = $alias.$key ";
    $sql .= "WHERE $joinAlias.$foreignKey NOT IN (" . implode(', ', $ids) . ") ";
    $sql .=  "AND $joinAlias.$associationForeignKey IN (";
    $sql .=   "SELECT $joinAlias.$associationForeignKey ";
    $sql .=   "FROM $prefix$joinTable AS $joinAlias ";
    $sql .=   "WHERE $joinAlias.$foreignKey IN (" . implode(', ', $ids) . ")";
    $sql .=  ") ";
    $sql .= "GROUP BY $joinAlias.$foreignKey ";
    $sql .= "ORDER BY $count DESC ";
    $sql .= "LIMIT {$config['limit']}";

    $result = $Model->query($sql);

    return $result;
  }
}
?>
Return current item: phTagr