1 <?php
2 /**
3 * @package Joomla.Libraries
4 * @subpackage Table
5 *
6 * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved.
7 * @license GNU General Public License version 2 or later; see LICENSE
8 */
9
10 defined('JPATH_PLATFORM') or die;
11
12 /**
13 * Abstract class defining methods that can be
14 * implemented by an Observer class of a JTable class (which is an Observable).
15 * Attaches $this Observer to the $table in the constructor.
16 * The classes extending this class should not be instanciated directly, as they
17 * are automatically instanciated by the JObserverMapper
18 *
19 * @since 3.1.2
20 */
21 class JTableObserverTags extends JTableObserver
22 {
23 /**
24 * Helper object for managing tags
25 *
26 * @var JHelperTags
27 * @since 3.1.2
28 */
29 protected $tagsHelper;
30
31 /**
32 * The pattern for this table's TypeAlias
33 *
34 * @var string
35 * @since 3.1.2
36 */
37 protected $typeAliasPattern = null;
38
39 /**
40 * Override for postStoreProcess param newTags, Set by setNewTags, used by onAfterStore and onBeforeStore
41 *
42 * @var array
43 * @since 3.1.2
44 */
45 protected $newTags = false;
46
47 /**
48 * Override for postStoreProcess param replaceTags. Set by setNewTags, used by onAfterStore
49 *
50 * @var boolean
51 * @since 3.1.2
52 */
53 protected $replaceTags = true;
54
55 /**
56 * Not public, so marking private and deprecated, but needed internally in parseTypeAlias for
57 * PHP < 5.4.0 as it's not passing context $this to closure function.
58 *
59 * @var JTableObserverTags
60 * @since 3.1.2
61 * @deprecated Never use this
62 * @private
63 */
64 public static $_myTableForPregreplaceOnly;
65
66 /**
67 * Creates the associated observer instance and attaches it to the $observableObject
68 * Creates the associated tags helper class instance
69 * $typeAlias can be of the form "{variableName}.type", automatically replacing {variableName} with table-instance variables variableName
70 *
71 * @param JObservableInterface $observableObject The subject object to be observed
72 * @param array $params ( 'typeAlias' => $typeAlias )
73 *
74 * @return JTableObserverTags
75 *
76 * @since 3.1.2
77 */
78 public static function createObserver(JObservableInterface $observableObject, $params = array())
79 {
80 $typeAlias = $params['typeAlias'];
81
82 $observer = new self($observableObject);
83
84 $observer->tagsHelper = new JHelperTags;
85 $observer->typeAliasPattern = $typeAlias;
86
87 return $observer;
88 }
89
90 /**
91 * Pre-processor for $table->store($updateNulls)
92 *
93 * @param boolean $updateNulls The result of the load
94 * @param string $tableKey The key of the table
95 *
96 * @return void
97 *
98 * @since 3.1.2
99 */
100 public function onBeforeStore($updateNulls, $tableKey)
101 {
102 $this->parseTypeAlias();
103
104 if (empty($this->table->tagsHelper->tags))
105 {
106 $this->tagsHelper->preStoreProcess($this->table);
107 }
108 else
109 {
110 $this->tagsHelper->preStoreProcess($this->table, (array) $this->table->tagsHelper->tags);
111 }
112 }
113
114 /**
115 * Post-processor for $table->store($updateNulls)
116 * You can change optional params newTags and replaceTags of tagsHelper with method setNewTagsToAdd
117 *
118 * @param boolean &$result The result of the load
119 *
120 * @return void
121 *
122 * @since 3.1.2
123 */
124 public function onAfterStore(&$result)
125 {
126 if ($result)
127 {
128 if (empty($this->table->tagsHelper->tags))
129 {
130 $result = $this->tagsHelper->postStoreProcess($this->table);
131 }
132 else
133 {
134 $result = $this->tagsHelper->postStoreProcess($this->table, $this->table->tagsHelper->tags);
135 }
136 // Restore default values for the optional params:
137 $this->newTags = array();
138 $this->replaceTags = true;
139 }
140 }
141
142 /**
143 * Pre-processor for $table->delete($pk)
144 *
145 * @param mixed $pk An optional primary key value to delete. If not set the instance property value is used.
146 *
147 * @return void
148 *
149 * @since 3.1.2
150 * @throws UnexpectedValueException
151 */
152 public function onBeforeDelete($pk)
153 {
154 $this->parseTypeAlias();
155 $this->tagsHelper->deleteTagData($this->table, $pk);
156 }
157
158 /**
159 * Sets the new tags to be added or to replace existing tags
160 *
161 * @param array $newTags New tags to be added to or replace current tags for an item
162 * @param boolean $replaceTags Replace tags (true) or add them (false)
163 *
164 * @return boolean
165 *
166 * @since 3.1.2
167 */
168 public function setNewTags($newTags, $replaceTags)
169 {
170 $this->parseTypeAlias();
171
172 return $this->tagsHelper->postStoreProcess($this->table, $newTags, $replaceTags);
173 }
174
175 /**
176 * Internal method
177 * Parses a TypeAlias of the form "{variableName}.type", replacing {variableName} with table-instance variables variableName
178 * Storing result into $this->tagsHelper->typeAlias
179 *
180 * @return void
181 *
182 * @since 3.1.2
183 */
184 protected function parseTypeAlias()
185 {
186 // Needed for PHP < 5.4.0 as it's not passing context $this to closure function
187 static::$_myTableForPregreplaceOnly = $this->table;
188
189 $this->tagsHelper->typeAlias = preg_replace_callback('/{([^}]+)}/',
190 function($matches)
191 {
192 return JTableObserverTags::$_myTableForPregreplaceOnly->{$matches[1]};
193 },
194 $this->typeAliasPattern
195 );
196 }
197 }
198