1 <?php
2
3 /*
4 * This file is part of the Icybee package.
5 *
6 * (c) Olivier Laviale <olivier.laviale@gmail.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12 namespace Icybee\Modules\Nodes;
13
14 use ICanBoogie\ActiveRecord;
15 use ICanBoogie\ActiveRecord\Query;
16 use ICanBoogie\DateTime;
17 use ICanBoogie\Exception;
18
19 /**
20 * Nodes model.
21 */
22 class Model extends \Icybee\ActiveRecord\Model\Constructor
23 {
24 /**
25 * If the {@link Node::$updated_at} property is not defined it is set to the current datetime.
26 *
27 * If the {@link Node::$slug} property is empty but the {@link Node::$title} property is
28 * defined its value is used.
29 *
30 * The {@link Node:$slug} property is always slugized.
31 */
32 public function save(array $properties, $key=null, array $options=[])
33 {
34 global $core;
35
36 if (!$key)
37 {
38 if (!array_key_exists(Node::UID, $properties)) // TODO-20121004: move this to operation
39 {
40 $properties[Node::UID] = $core->user_id;
41 }
42
43 if (empty($properties[Node::UUID]))
44 {
45 $properties[Node::UUID] = $this->obtain_uuid();
46 }
47 }
48
49 if (empty($properties[Node::SLUG]) && isset($properties[Node::TITLE]))
50 {
51 $properties[Node::SLUG] = $properties[Node::TITLE];
52 }
53
54 if (isset($properties[Node::SLUG]))
55 {
56 $properties[Node::SLUG] = slugize($properties[Node::SLUG], isset($properties[Node::LANGUAGE]) ? $properties[Node::LANGUAGE] : null);
57 }
58
59 return parent::save($properties, $key, $options);
60 }
61
62 /**
63 * Makes sure the node to delete is not used as a native target by other nodes.
64 *
65 * @throws Exception if the node to delete is the native target of another node.
66 */
67 public function delete($key)
68 {
69 $native_refs = $this->select('nid')->filter_by_nativeid($key)->all(\PDO::FETCH_COLUMN);
70
71 if ($native_refs)
72 {
73 throw new Exception('Node record cannot be deleted because it is used as native source by the following records: \1', array(implode(', ', $native_refs)));
74 }
75
76 return parent::delete($key);
77 }
78
79 /**
80 * Alerts the query to match online records.
81 *
82 * @param Query $query
83 *
84 * @return Query
85 */
86 protected function scope_online(Query $query)
87 {
88 return $query->filter_by_is_online(true);
89 }
90
91 /**
92 * Alerts the query to match offline records.
93 *
94 * @param Query $query
95 *
96 * @return Query
97 */
98 protected function scope_offline(Query $query)
99 {
100 return $query->filter_by_is_online(false);
101 }
102
103 /**
104 * Alerts the query to match records visible on the current website.
105 *
106 * @param Query $query
107 *
108 * @return Query
109 */
110 protected function scope_visible(Query $query)
111 {
112 return $query->online->similar_site->similar_language;
113 }
114
115 /**
116 * Alerts the query to match records of a similar site.
117 *
118 * A record is considered of a similar website when it doesn't belong to a website
119 * (`siteid = 0') or it matches the specified website.
120 *
121 * @param Query $query
122 * @param int $siteid The identifier of the website to match. If the identifier is `null` the
123 * current website identifier is used instead.
124 *
125 * @return Query
126 */
127 protected function scope_similar_site(Query $query, $siteid=null)
128 {
129 global $core;
130
131 return $query->where('siteid = 0 OR siteid = ?', $siteid !== null ? $siteid : $core->site->siteid);
132 }
133
134 /**
135 * Alerts the query to match recors of a similar language.
136 *
137 * A record is considered of a similar language when it doesn't have a language defined
138 * (`language` = "") or it matches the specified language.
139 *
140 * @param Query $query
141 * @param string $language The language to match. If the language is `null` the current
142 * language is used instead.
143 *
144 * @return Query
145 */
146 protected function scope_similar_language(Query $query, $language=null)
147 {
148 global $core;
149
150 return $query->where('language = "" OR language = ?', $language !== null ? $language : $core->site->language);
151 }
152
153 /**
154 * Finds the users the records belong to.
155 *
156 * The `user` property of the records is set to the user they belong to.
157 *
158 * @param array $records
159 *
160 * @return array
161 */
162 public function including_user(array $records)
163 {
164 $keys = [];
165
166 foreach ($records as $record)
167 {
168 $keys[$record->uid] = $record;
169 }
170
171 $users = ActiveRecord\get_model('users')->find_using_constructor(array_keys($keys));
172
173 /* @var $user \Icybee\Modules\Users\User */
174
175 foreach ($users as $key => $user)
176 {
177 $keys[$key]->user = $user;
178 }
179
180 return $records;
181 }
182
183 /**
184 * Returns a UUID.
185 *
186 * @return string
187 */
188 public function obtain_uuid()
189 {
190 for (;;)
191 {
192 $uuid = \ICanBoogie\generate_v4_uuid();
193
194 if (!$this->filter_by_uuid($uuid)->exists)
195 {
196 return $uuid;
197 }
198 }
199 }
200 }