PluginProbe
Depicter — Popup & Slider Builder / trunk
Depicter — Popup & Slider Builder vtrunk
4.8.1 trunk 1.0.0 1.1.0 1.1.2 1.1.4 1.1.6 1.1.7 1.1.8 1.1.9 1.2.0 1.3.0 1.3.1 1.3.2 1.3.3 1.3.5 1.3.8 1.5.0 1.5.1 1.5.2 1.5.5 1.6.0 1.6.1 1.6.2 1.7.0 All 76 releases
depicter / app / src / Database / Repository / DocumentRepository.php

DocumentRepository.php in Depicter — Popup & Slider Builder trunk, at app/src/Database/Repository/DocumentRepository.php

1,001 lines 23.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Depicter\Database\Repository;
3
4 use Averta\Core\Utility\Arr;
5 use Averta\Core\Utility\JSON;
6 use Depicter;
7 use Depicter\Database\Entity\Document;
8 use Depicter\Document\Helper\Helper;
9 use Depicter\Exception\DocumentNotFoundException;
10 use Exception;
11 use TypeRocket\Database\Results;
12 use TypeRocket\Models\Model;
13
14 class DocumentRepository
15 {
16
17 /**
18 * Columns that the document list may be sorted by.
19 */
20 private const ALLOWED_ORDER_BY = [
21 'id', 'name', 'slug', 'type', 'author',
22 'sections_count', 'created_at', 'modified_at', 'status', 'parent'
23 ];
24
25 /**
26 * @var Document
27 */
28 private $document;
29
30
31 public function __construct(){
32 $this->document = Document::new();
33 }
34
35 /**
36 * @return Document
37 *
38 * @throws Exception
39 */
40 public function document()
41 {
42 return Document::new();
43 }
44
45
46 /**
47 * Save changes directly
48 *
49 * @param int $id
50 * @param array $properties
51 *
52 * @return array
53 * @throws Exception
54 */
55 public function saveEditorData( int $id = 0, array $properties = [] )
56 {
57
58 if ( $id && $document = $this->document()->findById( $id ) ) {
59 $this->document = $document;
60 }
61
62 if( isset( $properties['editor'] ) ){
63 $editor = $properties['editor'];
64 unset( $properties['editor'] );
65
66 $parsedObject = $this->getParsedEditorContent( $editor );
67
68 $properties['sections_count' ] = $parsedObject->getSectionsCount();
69 $properties['content' ] = JSON::normalize( $editor );
70 }
71
72 // validate if the slug is not taken before
73 if( isset( $properties['slug' ] ) ){
74 $properties['slug' ] = trim( $properties['slug' ] );
75
76 if( empty( $properties['slug' ] ) ){
77 throw new Exception('Slug cannot be empty.');
78 }
79 if( $this->checkSlug( $properties['slug' ], $id ) ){
80 throw new Exception('The slug is already taken by another document.');
81 }
82 }
83
84 // name cannot be empty string
85 if( isset( $properties['name' ] ) ){
86 $properties['name' ] = trim( $properties['name' ] );
87
88 if( empty( $properties['name' ] ) ){
89 throw new Exception('Name cannot be empty.');
90 }
91 }
92
93 if ( $properties['status'] == 'unpublished' ) {
94 $properties['status'] = 'draft';
95 $this->changeRevisionsStatus( $id, 'draft');
96 }
97
98 $result = $this->update( $id, $properties, true );
99
100 if( $properties['status'] == 'publish' ){
101 $this->addRevision( $id, $properties );
102 }
103
104 return [
105 'result' => $result,
106 'modifiedAt' => $result ? $this->document->getApiProperties()['modified_at'] : "",
107 'publishedAt' => $result ? $this->document->getLastPublishedAt() : ""
108 ];
109 }
110
111 /**
112 * @param $editorContent
113 *
114 * @return mixed
115 */
116 private function getParsedEditorContent( $editorContent ){
117 // Get editor data
118 $documentMapper = \Depicter::resolve('depicter.document.mapper');
119 return $documentMapper->hydrate( $editorContent )->get();
120 }
121
122 /**
123 * Creates new revision for a document
124 *
125 * @param int $id
126 * @param array $fields
127 *
128 * @return mixed
129 * @throws Exception
130 */
131 protected function addRevision( int $id = 0, array $fields = [] )
132 {
133 $fields['created_at'] = $this->document->getDateTime();
134 $fields['parent'] = $id;
135
136 // set type if was not available in $fields
137 if( empty( $fields['type'] ) ){
138 $fields['type'] = $this->getFieldValue( $id, 'type' );
139 }
140
141 // check if revisions limit exceed than 15 number then remove the oldest one
142 if( DEPICTER_REVISIONS ){
143 $this->checkRevisionsLimit( $id );
144 }
145
146 return $this->findOrCreate( 0, $fields);
147 }
148
149 /**
150 * change status of revisions
151 *
152 * @param int $id
153 * @param string $status
154 *
155 * @return void
156 * @throws Exception
157 */
158 public function changeRevisionsStatus( int $id, string $status ) {
159 $revisions = $this->document()->where( 'parent', $id)->findAll();
160 if ( !empty( $revisions ) ) {
161 $revisions = $revisions->get();
162 foreach( $revisions as $revision ) {
163 $revision->update(['status' => $status ]);
164 }
165 }
166 }
167
168 /**
169 * Reverts to a previously published checkpoint
170 *
171 * @param $documentId
172 * @param string $revisionId
173 *
174 * @return array|bool|false|int|object|Model|null
175 * @throws Exception
176 */
177 public function revert( $documentId, string $revisionId = '~1' ){
178
179 if( ! $parentDocument = $this->findOne( $documentId ) ){
180 throw new Exception('Document does not exist.');
181 }
182 // Set a valid $revisionId
183 if( "" === $revisionId || is_null( $revisionId ) ){
184 $revisionId = "~1";
185 }
186
187 $lastRevision = null;
188
189 // Reverting the status back by step number, prefixed by `~`
190 if( false !== strpos( $revisionId, '~' ) ){
191 $revisionOffset = (int) ltrim( $revisionId, '~' );
192 $lastRevision = $this->getRecentRevision( $documentId, $revisionOffset - 1 );
193 // revert by revision document ID
194 } elseif( is_numeric( $revisionId ) ){
195 $lastRevision = $this->findOne( $revisionId );
196 }
197
198 if( ! empty( $lastRevision ) ){
199 // Throw error if revision does not belong to the document
200 if( $parentDocument->getID() != $lastRevision->parent() ){
201 throw new Exception('Revision ID does not belong to this document.');
202 }
203 // Set revision editor data for document
204 $lastRevisionContent = \Depicter::document()->migrations()->apply( $lastRevision->content() );
205 $parentDocument->save( ['content' => $lastRevisionContent ] );
206
207 } else {
208 throw new Exception("Couldn't revert to the revision. No revision found for this checkpoint.");
209 }
210
211 $hits = Arr::camelizeKeys( $lastRevision->getApiProperties(), '_' );
212 return [ "hits" => $hits ];
213 }
214
215 /**
216 * Check for revisions limit number
217 *
218 * @param $id
219 *
220 * @throws Exception
221 */
222 protected function checkRevisionsLimit( $id ) {
223 $revisions = $this->document()->select('id')->where('parent', $id)->findAll();
224 if ( $revisions->count() >= DEPICTER_REVISIONS ) {
225 $this->document()->findById( $revisions->first()->id )->delete();
226 }
227 }
228
229 /**
230 * Save changes directly to current document
231 *
232 * @param array $fields
233 *
234 * @return array|Model|object|Results|null
235 */
236 public function all( array $fields = [] )
237 {
238 return $this->document->findAll()->get();
239 }
240
241 /**
242 * Save changes directly to current document
243 *
244 * @param array $fields
245 * @param array $args
246 *
247 * @return array
248 * @throws Exception
249 */
250 public function getList( array $fields = [], $args = [] )
251 {
252 $columnsName = !empty( $fields ) ? $fields : ['id', 'name', 'slug', 'type', 'author', 'sections_count', 'created_at', 'modified_at', 'thumbnail', 'status'];
253 $numberOfPages = '';
254
255 $documents = $this->select( $columnsName );
256
257 // if 'has' filter is set. valid values for 'has': form, shortcode
258 if ( is_array( $args['has'] ) ) {
259 if( in_array( 'form', $args['has'] ) ){
260 $documents = $documents->withMeta()->whereMeta('hasForm', "1");
261 } elseif( in_array( 'shortcode', $args['has'] ) ){
262 $documents = $documents->withMeta()->whereMeta('hasShortcode', "1");
263 }
264 }
265
266 if ( !empty( $args['orderBy'] ) && !empty( $args['order'] ) ) {
267 // Resolve ordering against a known column list, never raw request input.
268 $order = 'ASC' === strtoupper( (string) $args['order'] ) ? 'ASC' : 'DESC';
269 $orderBy = in_array( $args['orderBy'], self::ALLOWED_ORDER_BY, true ) ? $args['orderBy'] : 'modified_at';
270
271 $documents = $documents->orderBy( $orderBy, $order );
272 }
273
274 if ( !empty( $args['s'] ) ) {
275 $documents = $documents->where( 'name', 'like', '%' . $args['s'] . '%' );
276 }
277
278 if ( !empty( $args['status'] ) ) {
279 $documents = $documents->where( 'status', $args['status'] );
280 }
281
282 if ( !empty( $args['types'] ) ) {
283 $types = explode( ',', $args['types'] );
284 $where = [];
285 foreach( $types as $type ) {
286 $where[] = [
287 'column' => 'type',
288 'operator' => '=',
289 'value' => $type
290 ];
291
292 $where[] = 'OR';
293
294 if ( $type == 'slider' ) {
295 $where[] = [
296 'column' => 'type',
297 'operator' => '=',
298 'value' => 'custom'
299 ];
300
301 $where[] = 'OR';
302 }
303 }
304
305 array_pop( $where );
306
307 $documents = $documents->where( $where );
308 }
309
310 $total = $documents->count();
311
312 if ( !empty( $args['page'] ) && !empty( $args['perPage'] ) ) {
313 $pager = $documents->paginate( $args['perPage'], $args['page'] );
314 if ( $pager ) {
315 $numberOfPages = $pager->getNumberOfPages();
316 $documents = $pager->getResults();
317 } else {
318 $documents = [];
319 }
320
321 } else {
322 $documents = $documents->get();
323 }
324
325
326 $documents = $documents ? $documents->toArray() : [];
327
328 if ( $documents && empty( $fields ) ) {
329 $uploadDir = wp_upload_dir();
330 foreach ( $documents as $key => $document ) {
331 $documents[ $key ]['has'] = [];
332 if ( Depicter::metaRepository()->get( $document['id'], 'hasForm', false ) ) {
333 $documents[ $key ]['has'][] = 'form';
334 }
335 if ( Depicter::metaRepository()->get( $document['id'], 'hasShortcode', false ) ) {
336 $documents[ $key ]['has'][] = 'shortcode';
337 }
338
339 $documents[ $key ]['publishedAt'] = $this->getLastPublishedAt( $document );
340
341 if ( is_file( $uploadDir['basedir'] . '/depicter/preview-images/' . $document['id'] . '.png' ) ) {
342 $documents[ $key ]['previewImage'] = $uploadDir['baseurl'] . '/depicter/preview-images/' . $document['id'] . '.png';
343 } else {
344 $documents[ $key ]['previewImage'] = '';
345 }
346 }
347 }
348
349 if ( !empty( $numberOfPages ) ) {
350 return [
351 'page' => $args['page'],
352 'perPage' => $args['perPage'],
353 'total' => $total,
354 'numberOfPages' => $numberOfPages,
355 'documents' => $documents
356 ];
357 }
358
359 return $documents;
360 }
361
362 /**
363 * Queries records of documents with specified fields
364 *
365 * @param array $fields
366 *
367 * @return Document
368 * @throws Exception
369 */
370 public function select( array $fields = [] )
371 {
372 $columnsName = !empty( $fields ) ? $fields : ['id', 'name', 'slug', 'author', 'sections_count', 'created_at', 'modified_at', 'thumbnail', 'status'];
373 return $this->document()->reselect( $columnsName )->parents();
374 }
375
376 /**
377 * Save changes directly to current document
378 *
379 * @param array $fields
380 *
381 * @return mixed
382 */
383 public function save( array $fields = [] )
384 {
385 $fields = $this->getMergedFields( $fields );
386 return $this->document->save( $fields);
387 }
388
389 /**
390 * Updates a document by ID
391 *
392 * @param int $id
393 * @param array $fields
394 * @param bool $parentOnly Only update the record if is parent document
395 *
396 * @return mixed
397 * @throws Exception
398 */
399 public function update( int $id = 0, array $fields = [], bool $parentOnly = false )
400 {
401 if( $document = $this->document()->findById( $id ) ){
402 if( $parentOnly && $document->getFieldValue('parent') != 0 ){
403 throw new Exception('Updating revision is not allowed.');
404 }
405
406 $fields['modified_at'] = $document->getDateTime();
407 return $document->update( $fields );
408 }
409 return false;
410 }
411
412
413
414 /**
415 * Creates new document in database
416 *
417 * @return Document
418 * @throws Exception
419 */
420 public function create( $type = 'custom' )
421 {
422 $documentId = $this->findOrCreate(0,
423 $this->getMergedFields([
424 'slug' => $this->makeSlug(),
425 'type' => $type,
426 'created_at' => $this->document->getDateTime(),
427 'modified_at' => $this->document->getDateTime()
428 ])
429 );
430
431 $document = $this->document()->findById( $documentId );
432 $document->rename( $document->getFieldValue( 'name' ) . ' ' . $documentId );
433
434 return $document;
435 }
436
437 /**
438 * Renames a document.
439 *
440 * @param $id
441 * @param $name
442 *
443 * @return bool
444 */
445 public function rename( $id, $name )
446 {
447 if( $document = $this->document()->findById( $id ) ){
448 return $document->rename( $name );
449 }
450 return false;
451 }
452
453 /**
454 * Changes the document slug.
455 *
456 * @param $id
457 * @param $slug
458 *
459 * @return int
460 * @throws Exception
461 */
462 public function changeSlug( $id, $slug )
463 {
464 if( $this->checkSlug( $slug ) ){
465 throw new Exception("The slug is already in use.");
466 }
467 if( $document = $this->document()->findById( $id ) ){
468 return $document->changeSlug( $slug );
469 }
470 return false;
471 }
472
473 /**
474 * Duplicates a document.
475 *
476 * @param int $id
477 *
478 * @param bool $returnNew
479 *
480 * @return int
481 * @throws Exception
482 */
483 public function duplicate( int $id, bool $returnNew = false )
484 {
485 if( $document = $this->document()->findById( $id ) ){
486 $fields = $document->getProperties();
487
488 unset( $fields['id'] );
489
490 $fields['name'] = is_string( $fields['name'] ) ? $fields['name'] . ' copy' : $fields['name'];
491 $fields['slug'] = $this->makeSlug();
492 $fields['created_at'] = $this->document->getDateTime();
493
494 if( ! is_numeric( $fields['sections_count'] ) ){
495 unset( $fields['sections_count'] );
496 }
497 if( ! is_numeric( $fields['parent'] ) ){
498 unset( $fields['parent'] );
499 }
500 if( ! is_numeric( $fields['author'] ) ){
501 unset( $fields['author'] );
502 }
503 if( is_null( $fields['content'] ) ){
504 unset( $fields['content'] );
505 }
506 if( is_null( $fields['password'] ) ){
507 unset( $fields['password'] );
508 }
509 if( is_null( $fields['thumbnail'] ) ){
510 unset( $fields['thumbnail'] );
511 }
512
513 if ( !empty( $fields['content'] ) ) {
514 $fields['content'] = \Depicter::document()->migrations()->apply( $fields['content'] );
515 }
516
517 $metaRelationID = ! empty( $fields['parent'] ) ? $fields['parent'] : $id;
518 $fields['parent'] = 0;
519
520 $newId = $this->findOrCreate( 0, $fields );
521 Depicter::metaRepository()->duplicateAllMetaByRelationID( $metaRelationID, $newId );
522
523 return $this->document()->findById( $newId );
524 }
525
526 return false;
527 }
528
529 /**
530 * Removes a document.
531 *
532 * @param $id
533 *
534 * @return int
535 * @throws Exception
536 */
537 public function delete( $id )
538 {
539 if( $document = $this->document()->findById( $id ) ){
540 $revisions = $this->document()->select('id')->where('parent', $id )->get();
541 if ( $revisions ) {
542 $revisionIDs = wp_list_pluck( $revisions->toArray() , 'id' );
543 $this->document()->delete( $revisionIDs );
544 }
545 return $document->delete();
546 }
547 return false;
548 }
549
550 /**
551 * Find a document by ID
552 *
553 * @param integer $id
554 *
555 * @return mixed
556 * @throws Exception
557 */
558 public function findById( int $id )
559 {
560 return $this->document()->findById( $id );
561 }
562
563 /**
564 * Finds or creates new document in database
565 *
566 * @param integer $id
567 * @param array $fields
568 *
569 * @return mixed returns Document if exists or id of created document
570 * @throws Exception
571 */
572 public function findOrCreate( int $id, array $fields = [] )
573 {
574 $fields = $this->getMergedFields( $fields );
575
576 return $this->document()->findOrCreate( $id, $fields );
577 }
578
579 /**
580 * Retrieves the lst document
581 *
582 * @return array|bool|false|int|object|Model|null
583 * @throws Exception
584 */
585 public function getLastDocument()
586 {
587 return $this->document()->findAll()->orderBy('id', 'DESC')->first();
588 }
589
590 /**
591 * Make a unique slug
592 *
593 * @param string $slug
594 * @param int $id
595 *
596 * @return string
597 * @throws Exception
598 */
599 public function makeSlug( string $slug = '', int $id = 0 )
600 {
601 if( ! $id && $document = $this->getLastDocument() ){
602 $id = $document->getID();
603 }
604
605 if( ! $slug ){
606 $slug = 'document';
607 }
608
609 $newID = $id + 1;
610 $newSlug = $slug . '-' . $newID;
611
612 while( $this->checkSlug( $newSlug ) ){
613 $newID++;
614 $newSlug = $slug . '-' . $newID;
615 }
616
617 return $newSlug;
618 }
619
620 /**
621 * Rename document
622 *
623 * @param string $slug
624 *
625 * @param int $ignoreID The document ID to ignore on check
626 *
627 * @return bool
628 * @throws Exception
629 */
630 public function checkSlug( string $slug, int $ignoreID = 0 )
631 {
632 $document = $this->document();
633 $foundCount = $document->where('slug', $slug )
634 ->where('id', 'NOT LIKE', $ignoreID )
635 ->findAll()->count();
636
637 if( $foundCount > 0 ){
638 unset( $document );
639 return true;
640 }
641
642 return false;
643 }
644
645 /**
646 * Retrieves default fields
647 *
648 * @return array
649 */
650 public function draftFields( $type = '')
651 {
652 return [
653 'name' => !empty($type) ? Helper::getDocumentTypeLabel( $type ) : __('Slider', 'depicter' ),
654 'status' => 'draft',
655 'author' => $this->getCurrentUserId()
656 ];
657
658 }
659
660 /**
661 * Retrieves current logged in user ID
662 *
663 * @return int
664 */
665 public function getCurrentUserId(){
666 return is_user_logged_in() ? get_current_user_id() : 0;
667 }
668
669 /**
670 * Retrieves default fields
671 *
672 * @return array
673 */
674 public function defaultFields()
675 {
676 return [
677 'name' => __('Untitled Slider', 'depicter'),
678 'slug' => '',
679 'type' => 'slider',
680 'author' => 0,
681 'parent' => 0,
682 'created_at' => $this->document->getDateTime(),
683 'sections_count'=> 0,
684 'thumbnail' => '',
685 'content' => '',
686 'password' => '',
687 'status' => 'draft'
688 ];
689
690 }
691
692 /**
693 * Merge fields with default fields
694 *
695 * @param $fields
696 *
697 * @return array
698 */
699 public function getMergedFields( $fields )
700 {
701 $type = $fields['type'] ?? '';
702
703 return Arr::merge( $fields, $this->draftFields( $type ) );
704 }
705
706 /**
707 * Get a revision of a document
708 *
709 * @param int $id Document ID
710 * @param int $offset offset
711 *
712 * @return array|Model|object|Results|null
713 * @throws Exception
714 */
715 public function getRecentRevision( int $id, int $offset = 0 ) {
716 $offset = max( $offset, 0 );
717 return $this->document()->orderBy('id', 'DESC')->where( 'parent', $id )->take( 1, $offset )->get();
718 }
719
720 /**
721 * Get list of revisions ID
722 *
723 * @param int $id Document ID
724 *
725 * @return array
726 * @throws Exception
727 */
728 public function getRevisionsID( int $id ) {
729 $revisions = $this->document()->select( ['id'])->orderBy( 'id', 'DESC')->where( 'parent', $id )->get();
730 return $revisions ? wp_list_pluck( $revisions->toArray(), 'id' ) : [];
731 }
732
733 /**
734 * @param array $document Document object in array
735 *
736 * @return mixed|string|null
737 * @throws Exception
738 */
739 public function getLastPublishedAt( array $document ) {
740 if ( $document['status'] == 'publish' ) {
741 return $document['modified_at'];
742 }
743
744 $lastRevision = $this->getRecentRevision( $document['id'] );
745
746 return $lastRevision && $lastRevision->status === 'publish' ? $lastRevision->modified_at : null;
747 }
748
749 /**
750 * Get a document entity
751 *
752 * @param null $documentId
753 * @param array $where
754 *
755 * @return array|bool|int|object|Results|Model|null
756 * @throws Exception
757 */
758 public function findOne( $documentId = null, array $where = [] ){
759
760 if( $documentId ){
761 $where['id'] = $documentId;
762 }
763
764 $documentEntity = $this->find( $where );
765
766 if ( ! $documentEntity->count() && !empty( $where['id'] ) ) {
767 $where['status'] = 'publish';
768 $where['parent'] = $where['id'];
769 unset( $where['id'] );
770
771 if ( ! $documentEntity = $this->find( $where )->orderBy('id', 'DESC') ) {
772 return false;
773 }
774 }
775
776 return $documentEntity->first();
777 }
778
779 /**
780 * Retrieves the content of document
781 *
782 * @param int $documentId
783 * @param array $where
784 *
785 * @return mixed
786 * @throws DocumentNotFoundException
787 */
788 public function getContent( int $documentId, array $where = [] ){
789 if( ! $documentEntity = $this->findOne( $documentId, $where ) ){
790 if ( isset( $where['status'] ) && is_array( $where['status'] ) ) {
791 unset( $where['status'][0] );
792 if( ! $documentEntity = $this->findOne( $documentId, $where ) ){
793 throw new DocumentNotFoundException( 'Document does not exist.', 404, $where );
794 }
795 } else {
796 throw new DocumentNotFoundException( 'Document does not exist.', 404, $where );
797 }
798 }
799 return $documentEntity->content();
800 }
801
802 /**
803 * Find based of where clauses
804 *
805 * @param array $where
806 *
807 * @return Document
808 * @throws Exception
809 */
810 public function find( array $where = [] ){
811 $documentEntity = $this->document();
812 foreach ( $where as $clause => $clauseValue ) {
813 $documentEntity->where( $clause, is_array( $clauseValue ) ? 'IN' : '=' , $clauseValue );
814 }
815
816 return $documentEntity;
817 }
818
819 /**
820 * Whether the document has been published so far or not
821 *
822 * @param int $documentId
823 *
824 * @return bool
825 */
826 public function isPublishedBefore( $documentId ){
827 try{
828 if( $this->getRecentRevision( $documentId ) ){
829 return true;
830 }
831
832 return $this->isPublished( $documentId );
833 } catch ( \Exception $exception ) {
834 return false;
835 }
836 }
837
838 /**
839 * Whether the document has published status or not
840 *
841 * @param int $documentId
842 *
843 * @return bool
844 * @throws Exception
845 */
846 public function isPublished( $documentId ){
847 try{
848 return $this->getStatus( $documentId ) === 'publish';
849 } catch ( \Exception $exception ) {
850 return false;
851 }
852 }
853
854 /**
855 * @param int $documentID Document ID
856 * @param string $fieldName Table field to retrieve value from
857 *
858 * @return array|mixed|object|string|null
859 */
860 public function getFieldValue( $documentID, $fieldName = 'name' ){
861
862 if( $document = $this->document()->findById( $documentID ) ){
863 return $document->getFieldValue( $fieldName );
864 }
865 return null;
866 }
867
868 /**
869 * Get status of document
870 *
871 * @param int $documentId
872 *
873 * @return string
874 * @throws Exception
875 */
876 public function getStatus( $documentId ) {
877 if( $document = $this->findById( $documentId ) ){
878 $document = $document->toArray();
879 return $document['status'];
880 }
881
882 return '';
883 }
884
885 /**
886 * Retrieves the url to preview image of document if exists
887 *
888 * @param int $documentID
889 *
890 * @return string URL of image if exits, otherwise, empty string
891 */
892 public function getPreviewImageUrl( int $documentID ){
893 if( file_exists( $this->getPreviewImagePath( $documentID ) ) ){
894 return Depicter::storage()->uploads()->getBaseUrl() . $this->getPreviewRelativeImagePath( $documentID );
895 }
896 return '';
897 }
898
899 /**
900 * Retrieves the path to preview image of a document
901 *
902 * @param int $documentID
903 *
904 * @return string
905 */
906 public function getPreviewImagePath( int $documentID ){
907 return Depicter::storage()->uploads()->getBaseDirectory() . $this->getPreviewRelativeImagePath( $documentID );
908 }
909
910 /**
911 * Writes preview image to the disk
912 *
913 * @param int $documentID
914 * @param string $imageContent
915 *
916 * @return bool
917 */
918 public function savePreviewImage( int $documentID, string $imageContent ){
919 return Depicter::storage()->filesystem()->write(
920 $this->getPreviewImagePath( $documentID ),
921 (string) $imageContent
922 );
923 }
924
925 /**
926 * Retrieves the relative path to preview image of a document
927 *
928 * @param $documentID
929 *
930 * @return string
931 */
932 protected function getPreviewRelativeImagePath( $documentID ){
933 return '/depicter/preview-images/' . $documentID . '.png';
934 }
935
936 /**
937 * Retrieves IDs of all conditional documents
938 *
939 * @return array|object
940 */
941 public function getConditionalDocumentIDs(){
942
943 try{
944 // get all main documents with conditional friendly types
945 $parents = $this->document()
946 ->reselect(['id'])
947 ->appendRawWhere( 'and', " `type` in ('popup', 'banner-bar')" )
948 ->where('status', 'publish')
949 ->where('parent', '0')
950 ->get();
951 $parents = $parents ? $parents->toArray() : [];
952
953 $parents = array_map( function( $record ){
954 return $record['id'];
955 }, $parents );
956
957 // get published revisions with conditional friendly types
958 $revisions = $this->document()
959 ->reselect(['parent'])
960 ->appendRawWhere( 'and', " `type` in ('popup', 'banner-bar')" )
961 ->where('status', 'publish')
962 ->where('parent', 'NOT LIKE', '0' )
963 ->get();
964
965 $revisions = $revisions ? $revisions->toArray() : [];
966 $revisionParents = array_map( function( $record ){
967 return $record['parent'];
968 }, $revisions );
969
970 return array_unique( Arr::merge( $revisionParents, $parents ) );
971
972 } catch ( \Exception $exception ) {
973 return [];
974 }
975 }
976
977 /**
978 * Get number of published documents
979 *
980 * @return int
981 */
982 public function getNumberOfPublishedDocuments(){
983 try{
984 $publishedDocuments = $this->document()->where( 'parent', '0' )->published()->count();
985 $draftDocuments = $this->document()->select('id')->where( 'parent', '0' )->draft()->findAll()->get();
986 if ( $draftDocuments ) {
987 $draftDocuments = $draftDocuments->toArray();
988 foreach ( $draftDocuments as $document ) {
989 if ( $this->isPublishedBefore( $document['id'] ) ) {
990 ++$publishedDocuments;
991 }
992 }
993 }
994
995 return $publishedDocuments;
996 } catch ( Exception $e ){
997 return 0;
998 }
999 }
1000 }
1001