* @license PHP License * @package wb * @subpackage Markup */ /** * Datasource Reference * * Things that refer to other things :-) * * @version 0.1.0 * @package wb * @subpackage Markup */ class WBDatasource_Reference extends WBStdClass implements WBDatasource_Callback { /** * table name: reference */ const TABLE_REFERENCE = 'reference'; /** * table name: dictionary url */ const TABLE_URL = 'url'; /** * * @var WBDatasource_Table */ private $table; /** * URL * @var WBDictionary_URL */ private $url; /** * Additional URL path in page layout * @var string */ private $urlPath; /** * Current list of references * @var array */ private $list; /** * current default namespace * @var string */ private $ns = ''; /** * current default tag * @var string */ private $tag = ''; /** * Resolve URL id to actual URL string * @var bool */ private $urlResolve = true; /** * URLs primary key column in database * @var string */ private $urlPrimary; /** * Constructor * * Init table access */ public function __construct($parameter = array()) { WBClass::load('WBDatasource_Table' , 'WBDictionary_URL'); $this->table = WBClass::create('WBDatasource_Table'); $this->url = WBClass::create('WBDictionary_URL'); $this->urlPrimary = $this->table->getIdentifier('url'); } /** * Set namespace * * @param string $ns * @return WBDatasource_Reference self */ public function setNamespace($ns = '') { $this->ns = $ns; return $this; } /** * Set tag * * @param string $ns * @return WBDatasource_Reference self */ public function setTag($tag = '') { $this->tag = $tag; return $this; } /** * Get list of references for id * * @param string $id * @param string $ns namespace (optionally) * @param string $tag tag (optionally) * @return array */ public function get($id, $tag = null, $ns = null) { if (!isset($ns)) { $ns = $this->ns; } if (!isset($tag)) { $tag = $this->tag; } $clause = array(); $clause[] = array( 'field' => 'xid', 'value' => $id ); $clause[] = array( 'field' => 'xtag', 'value' => $tag ); $clause[] = array( 'field' => 'xnamespace', 'value' => $ns ); $options = array( 'callback' => $this ); return $this->table->get(self::TABLE_REFERENCE, null, null, $clause, $options); } /** * Set URL target for reference * * Set either object, URLid or simply just the URL-string * * @param WBDictionary_URL $url * @param string $path * @return WBDatasource_Reference self */ public function setUrl($url, $path = '') { $this->urlPath = $path; if ($url instanceof WBDictionary_URL) { $this->url = $url; return $this; } if (preg_match('/^d+$/', $url)) { $this->url->load($url); return $this; } $this->url->addWord($url); return $this; } /** * Add id to reference list * * @see save() * @param string $id * @param string $ns namespace (optionally) * @param string $tag tag (optionally) * @return array */ public function add($id, $tag = null, $ns = null) { if (!isset($ns)) { $ns = $this->ns; } if (!isset($tag)) { $tag = $this->tag; } $this->list[] = array( 'xid' => $id, 'xtag' => $tag, 'xnamespace' => $ns ); } public function save() { $this->deleteRecords(); $this->addRecords($this->list); $this->list = array(); } private function addRecords($list) { if (empty($list)) { return; } $proto = array( $this->urlPrimary => $this->url->getId(), 'path' => $this->urlPath, 'xnamespace' => '', 'xtag' => '', 'xid' => '' ); $save = array(); foreach ($list as $l) { $save[] = array_merge($proto, $l); } // nothing to save if (empty($save)) { return; } $this->table->save(self::TABLE_REFERENCE, '__new', $save); } private function deleteRecords() { $clause = array(); $clause[] = array( 'field' => $this->urlPrimary, 'value' => $this->url->getId() ); $clause[] = array( 'field' => 'path', 'value' => $this->urlPath ); $this->table->delete(self::TABLE_REFERENCE, null, null, $clause); } /** * Callback when receive whole entry * * @param string $src name of source * @param string $key * @param array $data loaded data * @return bool true on success */ public function onDatasourceGet($src, $key, &$data) { if (self::TABLE_REFERENCE != $src || !$this->urlResolve) { return true; } // resolve URL $this->url->load($data[$this->urlPrimary]); $data['url'] = $this->url->getWord(); $data['page'] = $data['url']; $page = explode('/', $data['page']); if (2 < count($page)) { $data['page'] = urldecode(array_pop($page)); } $all = $this->url->get(); $data['title'] = $all['title']; return true; } }