1 <?php
2
3 4 5 6 7 8 9 10
11
12 namespace Icybee\Modules\Nodes;
13
14 use ICanBoogie\ActiveRecord\Query;
15 use ICanBoogie\I18n;
16 use ICanBoogie\Route;
17
18 use Brickrouge\A;
19 use Brickrouge\Document;
20 use Brickrouge\Element;
21
22 use Icybee\ManageBlock\Column;
23
24 25 26
27 class ManageBlock extends \Icybee\ManageBlock
28 {
29 static protected function add_assets(Document $document)
30 {
31 parent::add_assets($document);
32
33 $document->css->add(DIR . 'public/module.css');
34 $document->js->add(DIR . 'public/module.js');
35 }
36
37 public function __construct(Module $module, array $attributes=[])
38 {
39 parent::__construct($module, $attributes + [
40
41 self::T_ORDER_BY => [ Node::UPDATED_AT, 'desc' ]
42
43 ]);
44 }
45
46 47 48 49 50 51 52 53 54 55
56 protected function get_available_columns()
57 {
58 return array_merge(parent::get_available_columns(), [
59
60 Node::TITLE => __CLASS__ . '\TitleColumn',
61 'url' => __CLASS__ . '\URLColumn',
62 Node::IS_ONLINE => __CLASS__ . '\IsOnlineColumn',
63 Node::UID => 'Icybee\Modules\Users\ManageBlock\UserColumn',
64 Node::CREATED_AT => 'Icybee\ManageBlock\DateTimeColumn',
65 Node::UPDATED_AT => 'Icybee\ManageBlock\DateTimeColumn'
66
67 ]);
68 }
69
70 71 72 73 74 75
76 protected function get_available_jobs()
77 {
78 return array_merge(parent::get_available_jobs(), [
79
80 'online' => I18n\t('online.operation.short_title'),
81 'offline' => I18n\t('offline.operation.short_title')
82
83 ]);
84 }
85
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
111
112 113 114 115
116 protected function alter_query(Query $query, array $filters)
117 {
118 return parent::alter_query($query, $filters)
119 ->filter_by_constructor($this->module->id)
120 ->similar_site;
121 }
122
123
124 protected function __deprecated__render_cell_title($record, $property)
125 {
126 global $core;
127 static $languages;
128 static $languages_count;
129
130 if ($languages === null)
131 {
132 $languages = $core->models['sites']->count('language');
133 $languages_count = count($languages);
134 }
135
136 $title = $record->$property;
137 $label = $title ? \ICanBoogie\escape(\ICanBoogie\shorten($title, 52, .75, $shortened)) : $this->t('<em>no title</em>');
138
139 if ($shortened)
140 {
141 $label = str_replace('…', '<span class="light">…</span>', $label);
142 }
143
144 $rc = '';
145
146 if ($rc)
147 {
148 $rc .= ' ';
149 }
150
151 $rc .= new Element('a', [
152
153 Element::INNER_HTML => $label,
154
155 'class' => 'edit',
156 'href' => \ICanBoogie\Routing\contextualize("/admin/{$record->constructor}/{$record->nid}/edit"),
157 'title' => $shortened ? $this->t('edit_named', [ ':title' => $title ? $title : 'unnamed' ]) : $this->t('edit'),
158
159 ]);
160
161 $metas = '';
162
163 $language = $record->language;
164
165 if ($languages_count > 1 && $language != $core->site->language)
166 {
167 $metas .= ', <span class="language">' . ($language ? $language : 'multilingue') . '</span>';
168 }
169
170 if (!$record->siteid)
171 {
172 $metas .= ', multisite';
173 }
174
175 if ($metas)
176 {
177 $rc .= '<span class="metas small light">:' . substr($metas, 2) . '</span>';
178 }
179
180 return $rc;
181 }
182 }
183
184 namespace Icybee\Modules\Nodes\ManageBlock;
185
186 use Brickrouge\A;
187 use Brickrouge\Element;
188
189 use ICanBoogie\ActiveRecord\Query;
190 use ICanBoogie\I18n;
191
192 use Icybee\ManageBlock\Column;
193 use Icybee\ManageBlock\FilterDecorator;
194
195 class EditDecorator extends \Icybee\ManageBlock\EditDecorator
196 {
197 198 199 200
201 public function render()
202 {
203 $element = parent::render();
204 $component = $this->component;
205 $html = $component ? \ICanBoogie\escape(\ICanBoogie\shorten($component, 52, .75, $shortened)) : I18n\t('<em>no title</em>');
206
207 if (!$shortened)
208 {
209 return $element;
210 }
211
212 $element[Element::INNER_HTML] = str_replace('…', '<span class="light">…</span>', $html);
213 $element['title'] = I18n\t('manage.edit_named', [ ':title' => $component ? $component : 'unnamed' ]);
214
215 return $element;
216 }
217 }
218
219 220 221
222 class TitleColumn extends Column
223 {
224 public function __construct(\Icybee\ManageBlock $manager, $id, array $options=[])
225 {
226 parent::__construct($manager, $id, [
227
228 'discreet' => false
229
230 ]);
231 }
232
233 public function render_cell($record)
234 {
235 return new EditDecorator($record->title, $record);
236 }
237 }
238
239 240 241
242 class URLColumn extends Column
243 {
244 public function __construct(\Icybee\ManageBlock $manager, $id, array $options=[])
245 {
246 parent::__construct($manager, $id, [
247
248 'title' => null,
249 'class' => 'cell-fitted',
250 'orderable' => false
251
252 ]);
253 }
254
255 public function render_cell($record)
256 {
257 $url = $record->url;
258
259 if (!$url || $url{0} == '#')
260 {
261 return;
262 }
263
264 return new A('', $url, [
265
266 'title' => $this->manager->t('View this entry on the website'),
267 'class' => 'icon-external-link',
268 'target' => '_blank'
269
270 ]);
271 }
272 }
273
274 275 276
277 class IsOnlineColumn extends \Icybee\ManageBlock\BooleanColumn
278 {
279 public function __construct(\Icybee\ManageBlock $manager, $id, array $options=[])
280 {
281 parent::__construct($manager, $id, $options + [
282
283 'filters' => [
284
285 'options' => [
286
287 '=1' => 'Online',
288 '=0' => 'Offline'
289
290 ]
291
292 ],
293
294 'cell_renderer' => __NAMESPACE__ . '\IsOnlineCellRenderer'
295
296 ]);
297 }
298 }
299
300 301 302
303 class IsOnlineCellRenderer extends \Icybee\ManageBlock\BooleanCellRenderer
304 {
305 306 307
308 public function __invoke($record, $property)
309 {
310 $element = parent::__invoke($record, $property);
311 $element['title'] = "Publish or unpublish the record form the website";
312
313 return $element;
314 }
315 }
316
317 318 319
320 class TranslationsColumn extends Column
321 {
322 public function __construct(\Icybee\ManageBlock $manager, $id, array $options=[])
323 {
324 parent::__construct($manager, $id, $options + [
325
326 'orderable' => false
327
328 ]);
329 }
330
331 public function alter_records(array $records)
332 {
333 $records = parent::alter_records($records);
334
335 $this->resolve_translations($records);
336
337 return $records;
338 }
339
340 protected $translations_by_records;
341
342 protected function resolve_translations(array $records)
343 {
344 global $core;
345
346 $translations = [];
347 $translations_by_records = [];
348
349 $site = $core->site;
350 $sites = $core->models['sites'];
351 $site_translations = $site->translations;
352
353 if (!$site_translations)
354 {
355 return;
356 }
357
358 $site_translations_ids = [];
359
360 foreach ($site_translations as $site_translation)
361 {
362 $site_translations_ids[] = $site_translation->siteid;
363 }
364
365 if ($site->nativeid)
366 {
367 foreach ($records as $record)
368 {
369 $nativeid = $record->nativeid;
370
371 if (!$nativeid)
372 {
373 continue;
374 }
375
376 $translations[$nativeid] = true;
377 $translations_by_records[$record->nid][$nativeid] = true;
378 }
379 }
380 else
381 {
382 $native_ids = [];
383
384 foreach ($records as $record)
385 {
386 $native_ids[] = $record->nid;
387 }
388
389 if (!$native_ids)
390 {
391 return;
392 }
393
394 $translations_raw = $core->models['nodes']
395 ->select('siteid, nativeid, language, nid')
396 ->where([ 'nativeid' => $native_ids, 'siteid' => $site_translations_ids ])
397 ->order('FIELD(siteid, ' . implode(',', $site_translations_ids) . ')')
398 ->all;
399
400 if (!$translations_raw)
401 {
402 return;
403 }
404
405 foreach ($translations_raw as $translation)
406 {
407 $translations_by_records[$translation['nativeid']][$translation['nid']] = [
408
409 'site' => $sites[$translation['siteid']],
410 'siteid' => $translation['siteid'],
411 'language' => $translation['language']
412
413 ];
414 }
415
416 $this->translations_by_records = $translations_by_records;
417
418 return;
419 }
420
421 if (!$translations)
422 {
423 return;
424 }
425
426 $translations = array_keys($translations);
427 $ids = implode(',', $translations);
428
429 $infos = $core->models['nodes']
430 ->select('siteid, language')
431 ->where('nid IN(' . $ids . ')')
432 ->order('FIELD(nid, ' . $ids . ')')
433 ->all;
434
435 $translations = array_combine($translations, $infos);
436
437 foreach ($translations_by_records as $nid => $nt)
438 {
439 foreach (array_keys($nt) as $nativeid)
440 {
441 $translation = $translations[$nativeid];
442 $translation['site'] = $sites[$translation['siteid']];
443
444 $translations_by_records[$nid][$nativeid] = $translation;
445 }
446 }
447
448 $this->translations_by_records = $translations_by_records;
449 }
450
451 public function render_cell($record)
452 {
453 if (empty($this->translations_by_records[$record->nid]))
454 {
455 return;
456 }
457
458 $translations = $this->translations_by_records[$record->nid];
459
460 $rc = '';
461
462 foreach ($translations as $nativeid => $translation)
463 {
464 $rc .= ', <a href="' . $translation['site']->url . '/admin/' . $record->constructor . '/' . $nativeid . '/edit">' . $translation['language'] . '</a>';
465 }
466
467 return '<span class="translations">' . substr($rc, 2) . '</span>';
468 }
469 }