Completed
Push — master ( 83bda3...00ca69 )
by Rasmus
02:04
created

ContentController::initialize()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 14
ccs 12
cts 12
cp 1
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 11
nc 2
nop 0
crap 2
1
<?php
2
namespace Chp\TextContent;
3
4 1
include_once(__DIR__ . '/../../app/config/text-content.php');
5
6
/**
7
 * Text content controller
8
 * Made by Rasmus Berg (c) 2014-2017
9
 *
10
 * @property  object  $di         Anax-MVC class handler
11
 * @property  object  $request    Anax-MVC $_POST, $_GET and $_SERVER handler class
12
 * @property  object  $response   Anax-MVC Php Header class
13
 * @property  object  $url        Anax-MVC url-handler class
14
 * @property  object  $theme      Anax-MVC theme-handler class
15
 * @property  object  $views      Anax-MVC views-handler class
16
 * @property  object  $textFilter Anax-MVC textformat-handler class
17
 * @property  object  $db         PDO database class
18
 */
19
class ContentController implements \Anax\DI\IInjectionAware
20
{
21
  use \Anax\DI\TInjectable;
22
  
23
  /**
24
	 * Properties
25
	 */
26
  private $content;
27
  private $valid;
28
  private $contentPerPage; // Limit contents on list page
29
  private $urlPrefix;
30
  private $miniLength;
31
  
32
  /**
33
   * Initialize the controller
34
   *
35
   * @Return    Void
36
   */
37 7
  public function initialize(){
38 7
    if(!is_object($this->di))
39 7
      throw new \Anax\Exception\InternalServerErrorException('"$this->di" is not valid!');
40
    
41 7
    $this->content = new \Chp\TextContent\Content();
42 7
    $this->content->setDI($this->di);
43 7
    $this->valid = new \Chp\TextContent\ValidContent();
44 7
    $this->valid->setDI($this->di);
45 7
    $this->valid->initialize();
46
    
47 7
    $this->contentPerPage = CHP_TC_CONTENTPERPAGE;
48 7
    $this->urlPrefix      = CHP_TC_URLPREFIX;
49 7
    $this->miniLength     = CHP_TC_MINILENGTH;
50 7
  }
51
  
52
  /**
53
	 *  Index content - use listAction 
54
   *
55
	 * @Returns		Void
56
	 */
57
	public function indexAction(){
58
    $this->listAction();
59
  }
60
  
61
  /**
62
   * Setup content (If it allready exist it will restore database to begining)
63
   *
64
   * @Return    Void
65
   */
66
  public function setupAction(){
67
    $toDo   = "Restore or setup";
68
    $toWhat = "content database tables";
69
    $title  = "{$toDo} {$toWhat}";
70
    $form   = $this->confirmForm($this->url->create($this->urlPrefix . 'content/'));
71
    $status = $form->check();
72
 
73
    if($status === true){
74
    
75
      $this->db->dropTableIfExists('content')->execute();
76
77
      $this->db->createTable(
78
        'content',
79
        [
80
          'id'        => ['integer', 'primary key', 'not null', 'auto_increment'],
81
          'slug'      => ['char(80)'],
82
          'url'       => ['char(80)'],
83
          'type'      => ['char(80)'],
84
          'title'     => ['varchar(80)'],
85
          'ingress'   => ['text'],
86
          'text'      => ['text'],
87
          'filters'   => ['char(80)'],
88
          'author'    => ['integer', 'not null'],
89
          'published' => ['datetime'],
90
          'created'   => ['datetime'],
91
          'updated'   => ['datetime'],
92
          'deleted'   => ['datetime']
93
        ]
94
      )->execute();
95
      
96
      $this->db->insert(
97
        'content',
98
        ['slug', 'url', 'type', 'title', 'ingress', 'text', 'filters', 'author', 'published', 'created']
99
      );
100
101
      $now = date('Y-m-d H:i:s');
102
103
      $this->db->execute([
104
        'welcome_to_your_new_blog',
105
        NULL,
106
        'blog-post',
107
        'Welcome to your new blog',
108
        'This is example-blogg to show your new blog system!',
109
        'You can start blog by visit [url=' . $this->url->create($this->urlPrefix . "content/add/") . ']Add content[/url]',
110
        'bbcode',
111
        3,
112
        $now,
113
        $now
114
      ]);
115
      
116
      $this->db->execute([
117
        'welcome_to_your_new_page',
118
        'example-page',
119
        'page',
120
        'Welcome to your new page',
121
        'This is example-page to show your new page system!',
122
        'You can start makeing pages by visit [url=' . $this->url->create($this->urlPrefix . "content/add/") . ']Add content[/url]',
123
        'bbcode',
124
        3,
125
        $now,
126
        $now
127
      ]);
128
      
129
      $this->db->dropTableIfExists('content_tags')->execute();
130
      
131
      $this->db->createTable(
132
        'content_tags',
133
        [
134
          'idContent' => ['integer', 'not null'],
135
          'tag'       => ['varchar(150)', 'not null'],
136
          'slug'      => ['varchar(150)', 'not null']
137
        ]
138
      )->execute();
139
      
140
      $this->db->insert(
141
        'content_tags',
142
        ['idContent', 'tag', 'slug']
143
      );
144
      
145
      $this->db->execute([
146
        1,
147
        'New blog',
148
        'new_blog'
149
      ]);
150
151
      $this->db->execute([
152
        1,
153
        'Blog information',
154
        'blog_information'
155
      ]);
156
      
157
      $this->views->add('text-content/action-finish', [
158
          'title'   => $title,
159
          'msg'     => "Content and content tags database tables " . strtolower($toDo). " was successful!"
160
      ], 'main');
161
      
162
    }
163
    else{      
164
      $this->views->add('text-content/action', [
165
          'title'   => $title,
166
          'toDo'    => strtolower($toDo),
167
          'toWhat'  => $toWhat,
168
          'form'    => $form->getHTML(['novalidate' => true])
169
      ], 'main');
170
    }
171
    
172
    $this->theme->setTitle($title);
173
  }
174
  
175
  /**
176
	 *  List content (by type)
177
   *
178
	 * @Param     String    $type	  Type to list
179
   * @Param     Integer   $page   Page that paging is on
180
	 * @Return		Void
181
	 */
182
	public function listAction($type = null, $published = false, $page = null){
183
    $type      = ($this->valid->checkType($type)) ? $type : null;
184
    $title     = "All Content {$type} listed";
185
    $published = boolval($published);
186
187
    $form   = $this->listForm($type, $published);
188
    $form->check();
189
    
190
    if(!is_null($type))
191
      $contents = $this->content->getAllContentOfType($type, $page, $this->contentPerPage, $published);
192
    else
193
      $contents = $this->content->getAllContent($page, $this->contentPerPage, $published);
194
    $contents = $this->prepareListContent($contents);
195
    
196
    $this->theme->setTitle($title);
197
    $this->views->add('text-content/list', 
198
      [
199
        'title'     => $title,
200
        'form'      => $form->getHTML(array('novalidate' => true)),
201
        'contents' 	=> $contents,
202
        'addUrl'	  => $this->url->create($this->urlPrefix . 'content/add/'),
203
        'setupUrl'  => $this->url->create($this->urlPrefix . 'content/setup/')
204
      ]
205
    );
206
207
  }
208
  
209
  /**
210
   * Add content to database
211
   *
212
   * @Return    Void
213
   */
214
  public function addAction(){
215
    $action = "Add";
216
    $title = "{$action} content";
217
    
218
    $form = $this->contentForm();
219
    $form->check();
220
    
221
    $this->theme->setTitle($title);
222
    $this->views->add('text-content/post', 
223
      [
224
        'title'  => $title,
225
        'action' => $action,
226
        'form'   => $form->getHTML(array('novalidate' => true))
227
      ]);
228
  }
229
  
230
  /**
231
   * Edit content in database
232
   *
233
   * @Param     Integer   $id   Index for content to edit
234
   * @Return    Void
235
   */
236
  public function editAction($id = null){
237
    $action = "Edit";
238
    $title  = "{$action} content";
239
    $url    = $this->url->create($this->urlPrefix . 'content/');
240
    
241
    if(is_null($id) || !is_numeric($id))
242
      $this->response->redirect($url);
243
    
244
    $content = $this->content->getContentById($id, false);
245
    
246
    if(is_null($content->id))
247
      $this->response->redirect($url);
248
    
249
    $form = $this->contentForm($content);
250
    $form->check();
251
    
252
    $this->theme->setTitle($title);
253
    
254
    $this->views->add('text-content/post', 
255
      [
256
        'title'  => $title,
257
        'action' => $action,
258
        'form'   => $form->getHTML(array('novalidate' => true))
259
      ]
260
    );
261
  }
262
	
263
	/**
264
	 * Remove content
265
	 *
266
   * @Param   Integer  $id      Index to content to remove
267
	 * @Return  String   $error  	Database-error msg
268
	 */
269
	public function removeAction($id = null){
270
		$action = "Delete";
271
    $title = "Delete content";
272
    $url = $this->url->create($this->urlPrefix . "content/");
273
    
274
    if(is_null($id) || !is_numeric($id)){
275
			$this->response->redirect($url);
276
		}
277
    
278
    $content = $this->content->find($id);
279
    
280
    if(is_null($content->id)){
281
      $this->response->redirect($url);
282
    }
283
    
284
    $form = $this->confirmForm($url);
285
    $status = $form->Check();
286
    
287
    if ($status === true) {
288
      $now = date('Y-m-d H:i:s');
289
      
290
      $content->deleted = $now;
291
      $content->save();
292
      
293
      $this->response->redirect($url);
294
    }
295
    
296
    $this->theme->setTitle($title);
297
    $this->views->add('text-content/action', [
298
      'title'  => $title,
299
      'toDo'    => strtolower($action),
300
      'toWhat'  => strtolower($this->valid->getTypeTitle($content->type)),
301
      'which'   => htmlentities($content->title),
302
      'form'    => $form->getHTML(['novalidate' => true]),
303
    ], 'main');
304
	}
305
  
306
  /**
307
   * Prepare form to add or edit content
308
   *
309
   * @param   string    $type       Selected content-type
310
   * @param   boolean   $published  If content should be published already
311
   * @return  object    $form       CForm object
312
   */
313
  private function listForm($type = null, $published = false){
314
    
315
    $type_options      = array_merge([0 => "Select a type of content"], $this->valid->getTypes());
316
    
317
    $form = new \Mos\HTMLForm\CForm([], [
318
        'type' => [
319
          'type'        => 'select',
320
          'label'       => 'Type of content:',
321
          'options'     => $type_options,
322
          'value'       => (isset($type)) ? $type : ''
323
        ],
324
        'published' => [
325
          'type'        => 'checkbox',
326
          'label'       => 'Published',
327
          'checked'     => $published,
328
          'value'       => 1
329
        ],
330
        'submit' => [
331
          'value' 		=> 'Filter',
332
          'type'      => 'submit',
333
          'callback'  => function ($form) {
334
            $published = ($this->request->getPost('published')) ? 1 : 0;
335
            $type      = $form->Value('type');
336
            
337
            $this->response->redirect($this->url->create($this->urlPrefix . "content/list/{$type}/{$published}"));
338
          }
339
        ]
340
    ]);
341
    
342
    return $form;
343
  }
344
  
345
  /**
346
   * Prepare form to add or edit content
347
   *
348
   * @param   object    $values     Content values to add form elements
349
   * @return  object    $form       CForm object
350
   */
351 1
  private function contentForm($values = null){
352
    if(isset($values) && is_object($values)){
353
      $valArr = get_object_vars($values);
354
      extract($valArr);
355
    }
356
    
357
    $slug = (isset($slug)) ? $slug : NULL;
358
    
359
    $type_options      = $this->valid->getTypes();
360
    
361
    $form = new \Mos\HTMLForm\CForm([], [
362
        'id'      => [
363
          'type'        => 'hidden',
364
          'value'       => (isset($id)) ? $id : 0
365
        ],
366
        'title' => [
367
          'type'        => 'text',
368
          'label'       => 'Title: (Between ' . $this->miniLength . ' to 80 chars)',
369
          'maxlength'   => 80,
370
          'required'    => true,
371
          'value'       => (isset($title)) ? $title : '',
372
          'validation'  => [
373
                              'custom_test' => array(
374
                                'message' => 'Minmum length is ' . $this->miniLength . ' chars.', 
375
                                'test'    => array($this, 'minimumLength')
376
                              )
377
                           ]
378
        ],
379
        'url' => [
380 1
          'type'        => 'text',
381
          'label'       => 'Url:',
382
          'maxlength'   => 80,
383
          'value'       => (isset($url)) ? $url : '',
384
          'required'    => false, 
385
          'validation'  => [
386
                              'custom_test' => array(
387
                                'message' => 'Url is not in accepted-format for url:s (accepted characters is \'a-z0-9-_()\').', 
388
                                'test'    => array($this, 'validateSlug')
389
                              )
390
                           ]
391
        ],
392
        'ingress' => [
393
          'type'        => 'textarea',
394
          'label'       => 'Ingress: (minimum 3 chars)',
395
          'value'       => (isset($ingress)) ? $ingress : '',
396
          'required'    => true,
397
          'validation'  => [
398
                              'custom_test' => array(
399
                                'message' => 'Minmum length is ' . $this->miniLength . ' chars.', 
400
                                'test'    => array($this, 'minimumLength')
401
                              )
402
                           ]
403
        ],
404
        'text' => [
405
          'type'        => 'textarea',
406
        	'label'       => 'Text: (minimum ' . $this->miniLength . ' chars)',
407
          'value'       => (isset($text)) ? $text : '',
408
          'required'    => true,
409
          'validation'  => [
410
                            'custom_test' => array(
411
                              'message' => 'Minmum length is ' . $this->miniLength . ' chars.', 
412
                              'test'    => array($this, 'minimumLength')
413
                            )
414
                           ]
415
        ],
416
        'type' => [
417
          'type'        => 'select',
418
          'label'       => 'Type of content:',
419
          'options'     => $type_options,
420
          'value'       => (isset($type)) ? $type : '',
421
          'required'    => true,
422
          'validation'  => [
423
                              'not_empty',
424
                              'custom_test' => array(
425
                                'message' => 'You need to select a existing type.', 
426
                                'test'    => array($this, 'checkType')
427
                              )
428
                           ]
429
        ],
430
        'tags' => [
431
          'type'        => 'text',
432
          'label'       => 'Tags: (Seperate by \',\')',
433
          'value'       => (isset($tags)) ? $tags : '',
434
          'required'    => false
435
        ],
436
        'filters' => [
437
          'type'        => 'checkbox-multiple',
438
          'label'       => 'Text filter:',
439
          'values'      => $this->valid->getFilters(),
440
          'checked'     => (isset($filters)) ? explode(',', $filters) : array(),
441
          'validation'  => [
442
                              'custom_test' => array(
443
                                'message' => 'You need to select a existing type.', 
444
                                'test'    => array($this, 'checkFilter')
445
                              )
446
                           ]
447
        ],
448
        'published' => [
449
          'type'        => 'datetime',
450
          'label'       => 'Published: (YYYY-MM-DD HH:MM:SS)',
451
          'value'       => (isset($published)) ? $published : '',
452
          'validation'  => [
453
                              'custom_test' => array(
454
                                'message' => 'It need to be in a correct date and time with format: YYYY-MM-DD HH:MM:SS.', 
455
                                'test'    => array($this, 'checkDatetime')
456
                              )
457
                           ]
458
        ],
459
        'publishedNow' => [
460
          'type'        => 'checkbox',
461
          'label'       => 'Publish now:',
462
          'checked'     => (!isset($published) && !isset($id)),
463
          'value'       => 'yes'
464
        ],
465
        'submit' => [
466
          'value' 		=> 'Save',
467
          'type'      => 'submit',
468
          'callback'  => function ($form) use($slug) {
469
            return $this->saveContent($form, $slug);
470
          }
471
        ]
472
    ]);
473
    
474
    return $form;
475
  }
476
  
477
  /**
478
   * Prepare confirmation form
479
   *
480
   * @param   string   $returnUrl       Return url
481
   * @return  object   $form            Form-object
482
   */
483
  public function confirmForm($returnUrl = null){
484
    $returnUrl = (isset($returnUrl)) ? $returnUrl : $this->request->getBaseUrl();
485
    
486
    $form = new \Mos\HTMLForm\CForm([], [
487
        'submit' => [
488
          'type'     => 'submit',
489
          'value'    => 'Yes',
490
          'callback' => function() {
491
            return true;
492
          }
493
        ],
494
        'submit-no' => [
495
          'type'     => "submit",
496
          'value'    => 'No',
497
          'callback' => function() use($returnUrl) {
498
            $this->response->redirect($returnUrl);
499
          }
500
        ]
501
      ]
502
    );
503
		
504
    // Check the status of the form
505
    return $form;
506
  }
507
  
508
  /**
509
   * Save content to database
510
   *
511
   * @Param   Object    $form     Form object
512
   * @Param   String    $oldSlug  Old slug for content to compare
513
   * @Return  Boolean   false     If saving fail, return false
514
   */
515
  private function saveContent($form, $oldSlug = null){
516
    // Prepare content for saving
517
    $content = $this->prepareSaveContent($form, $oldSlug);
518
    
519
    // Save content
520
    $content = $this->content->save($content);
521
    
522
    // Saving fail
523
    if(!$this->content->id)
524
      return false;
525
    // Save tags for content to database
526
    else if($content['id'] != 0)
527
      $this->saveTags($form->Value('tags'), $this->content->id);
528
    
529
    $this->response->redirect($this->url->create($this->urlPrefix . "content/"));
530
  }
531
532
  /**
533
   * Save tags for content to database
534
   *
535
   * @Param   String   $tags     Tags for content
536
   * @Param   Int      $id       Content index
537
   */
538
  private function saveTags($tags, $id){
539
    $this->db->delete(
540
      'content_tags',
541
      'idContent = ?'
542
    )->execute([$id]);
543
    
544
    $this->db->insert(
545
      'content_tags',
546
      ['idContent', 'tag', 'slug']
547
    );
548
    
549
    if(isset($tags) && !is_null($tags)){
550
      $tagsArr = explode(",", $tags);
551
      
552
      foreach($tagsArr as $tag){
553
        $tag = trim($tag);
554
        $this->db->execute([
555
          $id,
556
          $tag,
557
          $this->valid->slugify($tag)
558
        ]);
559
      }
560
    }
561
  }
562
  
563
  /**
564
   * Prepare contents for show in list view
565
   *
566
   * @Param   Object  $contents   Object with content objects
567
   * @Return  Array   $results    Array with prepare content objects
568
   */
569 1
  public function prepareListContent($contents){
570 1
    $results = array();
571
    
572 1
    foreach($contents AS $key => $content){
573 1
      $available = $this->valid->checkIfAvailable($content->published);
574 1
      $results[$key] = (object)[];
575
      
576 1
      foreach($content as $key2 => $value){
577 1
        $results[$key]->{$key2} = $value;
578 1
      }
579
      
580 1
      $results[$key]->typeTxt      = $this->valid->getTypeTitle($content->type);
581 1
      $results[$key]->title        = htmlspecialchars($content->title, ENT_QUOTES);
582 1
      $results[$key]->editUrl      = $this->url->create($this->urlPrefix . "content/edit/{$content->id}");
583 1
      $results[$key]->removeUrl    = $this->url->create($this->urlPrefix . "content/remove/{$content->id}");
584 1
      $results[$key]->showUrl      = $this->valid->getUrlToContent($content);
585 1
      $results[$key]->available    = ((!$available) ? "not-" : null) . "published";
586 1
      $results[$key]->publishedTxt  = ($available) ? $contents[$key]->published : "Not published yet";
587 1
    }
588
    
589 1
    return $results;
590
  }
591
  /**
592
   * Prepare save of content to database
593
   *
594
   * @Param   Object    $form     Form object
595
   * @Param   String    $oldSlug  Old slug for content to compare
596
   * @Return  Array     $content  Prepare content array
597
   */  
598 1
  public function prepareSaveContent($form, $oldSlug = null){
599 1
    $now = date('Y-m-d H:i:s');
600
    
601
    // Prepare new slug
602 1
    $newSlug = $this->prepareNewSlug($form->Value('title'), $form->Value('type'), $oldSlug);
603
    
604
    $content = array(
605 1
      'title'     => $form->Value('title'),
606 1
      'slug'      => $newSlug,
607 1
      'url'       => $this->valid->slugify($form->Value('url')),
608 1
      'ingress'   => $form->Value('ingress'),
609 1
      'text'      => $form->Value('text'),
610 1
      'type'      => $form->Value('type'),
611 1
      'filters'   => ($form->Value('filters')) ? implode(",", $form->Value('filters')) : '',
612 1
      'published' => ($form->Value('publishedNow') && $form->Value('publishedNow') == 'yes') ? $now : $form->Value('published')
613 1
    );
614
    
615 1
    $id = ($form->Value('id')) ? intval($form->Value('id')) : 0;
616
    
617 1
    if($id != 0){
618 1
      $content['updated'] = $now;
619 1
      $content['id']      = $id;
620 1
    }
621
    else{
622 1
      $content['created'] = $now;
623 1
      $content['author']  = 0;//$this->user->getUserId();
624
    }
625
    
626 1
    return $content;
627
  }
628
  
629
  /**
630
   * Prepare new slug for content by title
631
   *
632
   * @Param   String    $title      Content title to make slug by
633
   * @Param   String    $type       Content type
634
   * @Param   String    $oldSlug    Old slug for content to compare
635
   * @Return  String    $newSlug    New unique slug for content
636
   */
637 1
  public function prepareNewSlug($title, $type, $oldSlug = null){
638 1
    $newSlug = $this->valid->slugify($title);
639
    
640 1
    if($oldSlug != $newSlug && isset($newSlug))
641 1
      $newSlug = $this->content->makeSlugToContent($newSlug, $type);
642
    
643 1
    return $newSlug;
644
  }
645
  
646
  /**
647
   * Validate minimum length
648
   *
649
   * @Param   String    $text       Text to validate
650
   * @Return  Boolean   True/False  Validate status
651
   */
652 1
  public function minimumLength($text = null){
653 1
    return $this->valid->minimumLength($text);
654
  }
655
  
656
  /**
657
   * Validate slug
658
   *
659
   * @Param   String    $slug       Slug to validate
660
   * @Return  Boolean   True/False  Validate status
661
   */
662 1
  public function validateSlug($slug = null){
663 1
    return $this->valid->validateSlug($slug);
664
  }
665
  
666
  /**
667
   * Validate type
668
   *
669
   * @Param   String    $type   Type to validate
670
   * @Return  Boolean   True/False  Validate status
671
   */
672 1
  public function checkType($type = null){
673 1
    return $this->valid->checkType($type);
674
  }
675
  
676
  /**
677
   * Validate filter
678
   *
679
   * @Param   String    $filter   Filter to validate
680
   * @Return  Boolean   True/False  Validate status
681
   */
682 1
  public function checkFilter($filter = null){
683 1
    return $this->valid->checkFilter($filter);
684
  }
685
  
686
  /**
687
   * Validate date time
688
   *
689
   * @Param   String    $datetime   Date time to validate
690
   * @Return  Boolean   True/False  Validate status
691
   */
692 1
  public function checkDatetime($datetime = null){
693 1
    return $this->valid->checkDatetime($datetime);
694
  }
695
}