Created
December 18, 2010 17:19
-
-
Save ludofleury/746671 to your computer and use it in GitHub Desktop.
lib/model/doctrine/FileRelation.class.php
Relational model between object model and file model
Implement LooseCoupling doctrine behavior concept from Christian Schaefer.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Template applied to models which are linked to File. | |
*/ | |
class Fileable extends Doctrine_Template | |
{ | |
protected $_options = array(); | |
protected $_files = array(); | |
public function __construct($options = null) | |
{ | |
$this->_options = $options; | |
} | |
public function setTableDefinition() | |
{ | |
$this->addListener(new FileableListener($this->_options)); | |
$this->hasMany('FileRelation as Files', array('local' => 'id', 'foreign' => 'object_id')); | |
} | |
# WIP : example of shortcut method | |
public function getImages() | |
{ | |
return ImageTable::getInstance()->createQuery('i INDEXBY fr.position') | |
->leftJoin('i.FileRelation fr ON fr.file_id = i.id') | |
->where('fr.file_type = ?','image') | |
->andWhere('fr.object_type = ?',get_class($this)) | |
->andWhere('fr.object_id = ?',$this->getPrimaryKey()) | |
->execute(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Listener which cascade CRUD action on the model to the File's relations. | |
*/ | |
class FileableListener extends Doctrine_Record_Listener | |
{ | |
protected $_options = array(); | |
public function __construct($options = null) | |
{ | |
$this->_options = $options; | |
} | |
public function preDqlSelect(Doctrine_Event $event) | |
{ | |
$query = $event->getQuery(); | |
$components = $this->_getDqlCallbackComponents($query); | |
foreach ($components as $alias => $component) | |
{ | |
if (isset($component['relation'])) | |
{ | |
$query->addWhere($alias.'.object_type = ?', get_class($event->getInvoker())); | |
} | |
} | |
} | |
/** | |
* Cascade delete to FileRelation | |
* @param Doctrine_Event $event | |
*/ | |
public function postDelete(Doctrine_Event $event) | |
{ | |
$record = $event->getInvoker(); | |
FileRelationTable::getInstance() | |
->createQuery('f') | |
->delete() | |
->where('f.object_type = ?', get_class($record)) | |
->andWhere('f.object_id = ?', $record->getPrimaryKey()) | |
->execute(); | |
} | |
/** | |
* Cascade update to FileRelation | |
* @param Doctrine_Event $event | |
*/ | |
public function preUpdate(Doctrine_Event $event) | |
{ | |
$record = $event->getInvoker(); | |
$modified = $record->getModified(); | |
if(isset($modified['id'])) | |
{ | |
FileRelationTable::getInstance() | |
->createQuery('f') | |
->update() | |
->set('object_id',$record->getId()) | |
->where('object_type = ?', get_class($record)) | |
->andWhere('object_id = ?', $record->getPrimaryKey()) | |
->execute(); | |
} | |
} | |
protected function _getDqlCallbackComponents($query) | |
{ | |
$params = $query->getParams(); | |
$componentsBefore = array(); | |
if ($query->isSubquery()) | |
{ | |
$componentsBefore = $query->getQueryComponents(); | |
} | |
$copy = $query->copy(); | |
$copy->getSqlQuery($params); | |
$componentsAfter = $copy->getQueryComponents(); | |
if ($componentsBefore !== $componentsAfter) | |
{ | |
return array_diff($componentsAfter, $componentsBefore); | |
} | |
else | |
{ | |
return $componentsAfter; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* FileRelation | |
* | |
* | |
* @package shop | |
* @subpackage model | |
* @author Christian Schaefer <caefer@ical.ly> | |
* @author Ludovic Fleury <ludovic.fleury@w3brothers.com> | |
* @version SVN: $Id: Builder.php 7490 2010-03-29 19:53:27Z jwage $ | |
*/ | |
class FileRelation extends BaseFileRelation | |
{ | |
protected $_objectCache = array(); | |
protected $_fileCache = array(); | |
public function getFile() | |
{ | |
if(false !== ($file = $this->getCachedFile($this->file_type, $this->file_id))) | |
{ | |
return $file; | |
} | |
elseif($this->file_type && $this->file_id) | |
{ | |
$file = Doctrine_Core::getTable($this->file_type)->find($this->file_id); | |
$this->setCachedFile($this->file_type, $this->file_id, $file); | |
return $file; | |
} | |
else | |
{ | |
return null; | |
} | |
} | |
public function setFile(File $file) | |
{ | |
$this->file_type = $this->_findObjectType($file); | |
$this->file_id = $this->_findObjectPrimaryKey($file); | |
$this->setCachedFile($this->file_type, $this->file_id, $file); | |
} | |
public function getCachedFile($type, $id) | |
{ | |
if(array_key_exists($type, $this->_fileCache) && array_key_exists($id, $this->_fileCache[$type])) | |
{ | |
return $this->_fileCache[$type][$id]; | |
} | |
return false; | |
} | |
public function setCachedFile($type, $id, $file) | |
{ | |
if(!array_key_exists($type, $this->_fileCache)) | |
{ | |
$this->_fileCache[$type] = array(); | |
} | |
$this->_fileCache[$type][$id] = $file; | |
} | |
public function getObject() | |
{ | |
if(false !== ($object = $this->getCachedObject($this->object_type, $this->object_id))) | |
{ | |
return $object; | |
} | |
else if($this->object_type && $this->object_id) | |
{ | |
$object = Doctrine_Core::getTable($this->object_type)->find($this->object_id); | |
$this->setCachedObject($this->object_type, $this->object_id, $object); | |
return $object; | |
} | |
else | |
{ | |
return null; | |
} | |
} | |
public function setObject($object) | |
{ | |
$this->object_type = $this->_findObjectType($object); | |
$this->object_id = $this->_findObjectPrimaryKey($object); | |
$this->setCachedObject($this->object_type, $this->object_id, $object); | |
} | |
public function getCachedObject($type, $id) | |
{ | |
if(array_key_exists($type, $this->_objectCache) && array_key_exists($id, $this->_objectCache[$type])) | |
{ | |
return $this->_objectCache[$type][$id]; | |
} | |
return false; | |
} | |
public function setCachedObject($type, $id, $object) | |
{ | |
if(!array_key_exists($type, $this->_objectCache)) | |
{ | |
$this->_objectCache[$type] = array(); | |
} | |
$this->_objectCache[$type][$id] = $object; | |
} | |
protected function _findObjectType($object) | |
{ | |
return get_class($object); | |
} | |
protected function _findObjectPrimaryKey($object) | |
{ | |
$identifier = $object->identifier(); | |
if(1 != count($identifier)) | |
{ | |
throw new Doctrine_Record_Exception("Couldn't set identifier. LooseCoupling does not support multi column primary keys!."); | |
} | |
return current($identifier); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment