Skip to content

Commit 9c2b637

Browse files
committed
Completed Tags and Users chapter.
1 parent 989d6d8 commit 9c2b637

30 files changed

Lines changed: 1406 additions & 4 deletions

‎config/routes.php‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,17 @@
4343
*/
4444
Router::defaultRouteClass(DashedRoute::class);
4545

46+
// New route we're adding for our tagged action.
47+
// The trailing `*` tells CakePHP that this action has
48+
// passed parameters.
49+
Router::scope(
50+
'/articles',
51+
['controller' => 'Articles'],
52+
function ($routes) {
53+
$routes->connect('/tagged/*', ['action' => 'tags']);
54+
}
55+
);
56+
4657
Router::scope('/', function (RouteBuilder $routes) {
4758
/**
4859
* Here, we are connecting '/' (base path) to a controller called 'Pages',

‎src/Controller/ArticlesController.php‎

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,21 @@ public function add()
3939
}
4040
$this->Flash->error(__('Unable to add your article.'));
4141
}
42+
// Get a list of tags.
43+
$tags = $this->Articles->Tags->find('list');
44+
45+
// Set tags to the view context
46+
$this->set('tags', $tags);
47+
4248
$this->set('article', $article);
4349
}
4450

4551
public function edit($slug)
4652
{
47-
$article = $this->Articles->findBySlug($slug)->firstOrFail();
53+
$article = $this->Articles
54+
->findBySlug($slug)
55+
->contain('Tags') // load associated Tags
56+
->firstOrFail();
4857
if ($this->request->is(['post', 'put'])) {
4958
$this->Articles->patchEntity($article, $this->request->getData());
5059
if ($this->Articles->save($article)) {
@@ -54,10 +63,15 @@ public function edit($slug)
5463
$this->Flash->error(__('Unable to update your article.'));
5564
}
5665

66+
// Get a list of tags.
67+
$tags = $this->Articles->Tags->find('list');
68+
69+
// Set tags to the view context
70+
$this->set('tags', $tags);
71+
5772
$this->set('article', $article);
5873
}
5974

60-
6175
public function delete($slug)
6276
{
6377
$this->request->allowMethod(['post', 'delete']);
@@ -68,4 +82,22 @@ public function delete($slug)
6882
return $this->redirect(['action' => 'index']);
6983
}
7084
}
85+
86+
public function tags()
87+
{
88+
// The 'pass' key is provided by CakePHP and contains all
89+
// the passed URL path segments in the request.
90+
$tags = $this->request->getParam('pass');
91+
92+
// Use the ArticlesTable to find tagged articles.
93+
$articles = $this->Articles->find('tagged', [
94+
'tags' => $tags
95+
]);
96+
97+
// Pass variables into the view template context.
98+
$this->set([
99+
'articles' => $articles,
100+
'tags' => $tags
101+
]);
102+
}
71103
}

‎src/Controller/TagsController.php‎

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
<?php
2+
namespace App\Controller;
3+
4+
use App\Controller\AppController;
5+
6+
/**
7+
* Tags Controller
8+
*
9+
* @property \App\Model\Table\TagsTable $Tags
10+
*
11+
* @method \App\Model\Entity\Tag[] paginate($object = null, array $settings = [])
12+
*/
13+
class TagsController extends AppController
14+
{
15+
16+
/**
17+
* Index method
18+
*
19+
* @return \Cake\Http\Response|void
20+
*/
21+
public function index()
22+
{
23+
$tags = $this->paginate($this->Tags);
24+
25+
$this->set(compact('tags'));
26+
$this->set('_serialize', ['tags']);
27+
}
28+
29+
/**
30+
* View method
31+
*
32+
* @param string|null $id Tag id.
33+
* @return \Cake\Http\Response|void
34+
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
35+
*/
36+
public function view($id = null)
37+
{
38+
$tag = $this->Tags->get($id, [
39+
'contain' => ['Articles']
40+
]);
41+
42+
$this->set('tag', $tag);
43+
$this->set('_serialize', ['tag']);
44+
}
45+
46+
/**
47+
* Add method
48+
*
49+
* @return \Cake\Http\Response|null Redirects on successful add, renders view otherwise.
50+
*/
51+
public function add()
52+
{
53+
$tag = $this->Tags->newEntity();
54+
if ($this->request->is('post')) {
55+
$tag = $this->Tags->patchEntity($tag, $this->request->getData());
56+
if ($this->Tags->save($tag)) {
57+
$this->Flash->success(__('The tag has been saved.'));
58+
59+
return $this->redirect(['action' => 'index']);
60+
}
61+
$this->Flash->error(__('The tag could not be saved. Please, try again.'));
62+
}
63+
$articles = $this->Tags->Articles->find('list', ['limit' => 200]);
64+
$this->set(compact('tag', 'articles'));
65+
$this->set('_serialize', ['tag']);
66+
}
67+
68+
/**
69+
* Edit method
70+
*
71+
* @param string|null $id Tag id.
72+
* @return \Cake\Http\Response|null Redirects on successful edit, renders view otherwise.
73+
* @throws \Cake\Network\Exception\NotFoundException When record not found.
74+
*/
75+
public function edit($id = null)
76+
{
77+
$tag = $this->Tags->get($id, [
78+
'contain' => ['Articles']
79+
]);
80+
if ($this->request->is(['patch', 'post', 'put'])) {
81+
$tag = $this->Tags->patchEntity($tag, $this->request->getData());
82+
if ($this->Tags->save($tag)) {
83+
$this->Flash->success(__('The tag has been saved.'));
84+
85+
return $this->redirect(['action' => 'index']);
86+
}
87+
$this->Flash->error(__('The tag could not be saved. Please, try again.'));
88+
}
89+
$articles = $this->Tags->Articles->find('list', ['limit' => 200]);
90+
$this->set(compact('tag', 'articles'));
91+
$this->set('_serialize', ['tag']);
92+
}
93+
94+
/**
95+
* Delete method
96+
*
97+
* @param string|null $id Tag id.
98+
* @return \Cake\Http\Response|null Redirects to index.
99+
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
100+
*/
101+
public function delete($id = null)
102+
{
103+
$this->request->allowMethod(['post', 'delete']);
104+
$tag = $this->Tags->get($id);
105+
if ($this->Tags->delete($tag)) {
106+
$this->Flash->success(__('The tag has been deleted.'));
107+
} else {
108+
$this->Flash->error(__('The tag could not be deleted. Please, try again.'));
109+
}
110+
111+
return $this->redirect(['action' => 'index']);
112+
}
113+
}

‎src/Controller/UsersController.php‎

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
<?php
2+
namespace App\Controller;
3+
4+
use App\Controller\AppController;
5+
6+
/**
7+
* Users Controller
8+
*
9+
* @property \App\Model\Table\UsersTable $Users
10+
*
11+
* @method \App\Model\Entity\User[] paginate($object = null, array $settings = [])
12+
*/
13+
class UsersController extends AppController
14+
{
15+
16+
/**
17+
* Index method
18+
*
19+
* @return \Cake\Http\Response|void
20+
*/
21+
public function index()
22+
{
23+
$users = $this->paginate($this->Users);
24+
25+
$this->set(compact('users'));
26+
$this->set('_serialize', ['users']);
27+
}
28+
29+
/**
30+
* View method
31+
*
32+
* @param string|null $id User id.
33+
* @return \Cake\Http\Response|void
34+
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
35+
*/
36+
public function view($id = null)
37+
{
38+
$user = $this->Users->get($id, [
39+
'contain' => ['Articles']
40+
]);
41+
42+
$this->set('user', $user);
43+
$this->set('_serialize', ['user']);
44+
}
45+
46+
/**
47+
* Add method
48+
*
49+
* @return \Cake\Http\Response|null Redirects on successful add, renders view otherwise.
50+
*/
51+
public function add()
52+
{
53+
$user = $this->Users->newEntity();
54+
if ($this->request->is('post')) {
55+
$user = $this->Users->patchEntity($user, $this->request->getData());
56+
if ($this->Users->save($user)) {
57+
$this->Flash->success(__('The user has been saved.'));
58+
59+
return $this->redirect(['action' => 'index']);
60+
}
61+
$this->Flash->error(__('The user could not be saved. Please, try again.'));
62+
}
63+
$this->set(compact('user'));
64+
$this->set('_serialize', ['user']);
65+
}
66+
67+
/**
68+
* Edit method
69+
*
70+
* @param string|null $id User id.
71+
* @return \Cake\Http\Response|null Redirects on successful edit, renders view otherwise.
72+
* @throws \Cake\Network\Exception\NotFoundException When record not found.
73+
*/
74+
public function edit($id = null)
75+
{
76+
$user = $this->Users->get($id, [
77+
'contain' => []
78+
]);
79+
if ($this->request->is(['patch', 'post', 'put'])) {
80+
$user = $this->Users->patchEntity($user, $this->request->getData());
81+
if ($this->Users->save($user)) {
82+
$this->Flash->success(__('The user has been saved.'));
83+
84+
return $this->redirect(['action' => 'index']);
85+
}
86+
$this->Flash->error(__('The user could not be saved. Please, try again.'));
87+
}
88+
$this->set(compact('user'));
89+
$this->set('_serialize', ['user']);
90+
}
91+
92+
/**
93+
* Delete method
94+
*
95+
* @param string|null $id User id.
96+
* @return \Cake\Http\Response|null Redirects to index.
97+
* @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
98+
*/
99+
public function delete($id = null)
100+
{
101+
$this->request->allowMethod(['post', 'delete']);
102+
$user = $this->Users->get($id);
103+
if ($this->Users->delete($user)) {
104+
$this->Flash->success(__('The user has been deleted.'));
105+
} else {
106+
$this->Flash->error(__('The user could not be deleted. Please, try again.'));
107+
}
108+
109+
return $this->redirect(['action' => 'index']);
110+
}
111+
}

‎src/Model/Entity/Article.php‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// src/Model/Entity/Article.php
33
namespace App\Model\Entity;
44

5+
use Cake\Collection\Collection;
56
use Cake\ORM\Entity;
67

78
class Article extends Entity
@@ -11,4 +12,19 @@ class Article extends Entity
1112
'id' => false,
1213
'slug' => false,
1314
];
15+
16+
protected function _getTagString()
17+
{
18+
if (isset($this->_properties['tag_string'])) {
19+
return $this->_properties['tag_string'];
20+
}
21+
if (empty($this->tags)) {
22+
return '';
23+
}
24+
$tags = new Collection($this->tags);
25+
$str = $tags->reduce(function ($string, $tag) {
26+
return $string . $tag->title . ', ';
27+
}, '');
28+
return trim($str, ', ');
29+
}
1430
}

‎src/Model/Entity/Tag.php‎

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
namespace App\Model\Entity;
3+
4+
use Cake\ORM\Entity;
5+
6+
/**
7+
* Tag Entity
8+
*
9+
* @property int $id
10+
* @property string $title
11+
* @property \Cake\I18n\FrozenTime $created
12+
* @property \Cake\I18n\FrozenTime $modified
13+
*
14+
* @property \App\Model\Entity\Article[] $articles
15+
*/
16+
class Tag extends Entity
17+
{
18+
19+
/**
20+
* Fields that can be mass assigned using newEntity() or patchEntity().
21+
*
22+
* Note that when '*' is set to true, this allows all unspecified fields to
23+
* be mass assigned. For security purposes, it is advised to set '*' to false
24+
* (or remove it), and explicitly make individual fields accessible as needed.
25+
*
26+
* @var array
27+
*/
28+
protected $_accessible = [
29+
'*' => true,
30+
'id' => false
31+
];
32+
}

0 commit comments

Comments
 (0)