Issues with CMS tutorial

I’m a first-time PHP frame user, but have written some fundamental PHP apps so I know my way around it enough. I used Oven to bake this cake (from the installation link on the first page of the tutorial), as I don’t have admin on my TTY access to my webhost and composer is not installed - that may be relevant to some of these issues - in which case that should be mentioned in the tutorial.

Here’s are some issues and suggestions for the tutorial. This does not include the error spotted here: CMS tutorial beforeSave with tag_string

Firstly it would be good to actually have a home screen, instead of manually typing …/articles - after all I would consider that relevant to building a home page. Even if its an automatic redirection to the …/articles.php page - in which case what is the correct CakePHP way of doing that? (I am assuming it’s an edit of ./templates/Pages/home.php - but what should actually be put in there?)
It could otherwise be maintained during the tutorial, adding the links as relevant, like the final logout link, thus rounding the tutorial off within a package.

Bad link: -
On the /articles page there is a link in the top right titled “API” which refers to https://api.cakephp.org/4/ which gives [me] a 404 error.

Wrong instruction: -
https://book.cakephp.org/4/en/tutorials-and-examples/cms/tags-and-users.html#updating-the-views
“In src/Template/Articles/view.php add the line as shown:” should be “In Template/Articles/view.php add the line as shown:”. I know this is obvious to everyone else, but still learning the layout means its not obvious first time around.

Wrong code: -
https://book.cakephp.org/4/en/tutorials-and-examples/cms/articles-controller.html#add-edit-action
$article = $this->Articles
->findBySlug($slug)
->contain(‘Tags’) // load associated Tags
->firstOrFail();

should be

$article = $this->Articles
->findBySlug($slug)
->firstOrFail();

No tag. Again it may be obvious looking, but at this stage in the tutorial I didn’t know that “tag” was not a built-in Cake reserved-word, or object property (as a Delphi programmer that could be an assumption). The tags are added on the next page of the tutorial, but I had debugged this before moving on and thus realising then what it was!

Misinformation: -
https://book.cakephp.org/4/en/tutorials-and-examples/cms/articles-controller.html#adding-articles
The comment “// Hardcoding the user_id is temporary, and will be removed later when we build authentication out.”
But it isn’t. Even in the final version of src/Controller/ArticlesController.php that comment is still there. I would like to be able to attribute the person who wrote the article to the user logged in. I tried this: -
$article->user_id = $this->Auth->User(‘user_id’);
$article->user_id = $this->Auth->User(‘id’);
$article->user_id = $this->Auth->Users(‘user_id’);
$article->user_id = $this->Auth->Users(‘id’);
$article->user_id = $this->Authentication->User(‘id’);
and all variations of field names, case etc.
Also I tried this: -
$u = $this->Auth->user();
$uid = $u[‘User’][‘id’];
$article->user_id = $uid;
Am I missing a uses unit?
I read here https://stackoverflow.com/a/19169289/530047 there are other ways to get the user id, but as I am in a Controller here I want to use the command recommended for a controller.
Nevertheless, these also did not work: -
$article->user_id = $this->Session->read(‘Auth.User.id’);
$article->user_id = CakeSession::read(‘Auth.User.id’);
article->user_id = _SESSION[‘Auth’][‘User’][‘id’];
So I’m stumped on this one! (I still I may be missing a unit?)

I downloaded the source provided on github and it had: -
// Added: Set the user_id from the session.
$article->user_id = $this->Auth->user(‘id’);
Which, also, yielded as error (as expected as I had already tried this) of: -
Notice (1024): Undefined property: ArticlesController::$Auth in …/src/Controller/ArticlesController.php on line 41 [CORE/src/Controller/Controller.php, line 314]
Error: Call to a member function user() on null

Code is different on github: -
Either the tutorial is out of date, or github is. But github is different, with lines like: -
$this->Auth->allow([‘tags’]);
in src/Controller/ArticlesController.php initialize()
Note that adding that line caused my app to crash with “Call to a member function allow() on null”.

So as both our apps are broken I have run out of options!! At this point I have given up trying to debug either of them.


Allow me to say thanks for sharing this wonderful product. I hope with these minor adjustments and additions this tutorial will be easier to follow for others.

Cheers
Jonathan

as I don’t have admin on my TTY access to my webhost and composer is not installed

Developing remotely is bad bad idea and will lead to various problems in general. Always develop locally and then deploy to remote.

On the /articles page there is a link in the top right titled “API” which refers to https://api.cakephp.org/4/ which gives [me] a 404 error.

Due to various technical issue we still don’t have the API docs for v4 available sorry about that.

Even in the final version of src/Controller/ArticlesController.php that comment is still there

Seems you missed one or more steps of the tutorial CMS Tutorial - Authorization - 4.x shows how to get the user id from the Authentication component to replaced the hardcoded one.

downloaded the source provided on github and it had

Oops, seems we have missed updating the cakephp/cms-tutorial tutorial repo for CakePHP 4. I have opened a ticket for it.

I have submitted a patch for couple of other issues you have noted Fixes to CMS tutorial by ADmad · Pull Request #6431 · cakephp/docs · GitHub.

(Sorry, new users can only put 2 links in a post … so please forgive all the broken links I was forced to create here. It also destroyed the formatting!)

Thank you so much for helping. I am now developing locally and have started the tutorial all over from scratch. And I did miss some of the Authorization section, which will be explained in this novella!

At the outset this is an awesome app, I’m having fun just doing the tutorial, again!

I must also state that I’m kind of a rather precise person - so please feel free to ignore everything I say, I know my thoroughness doesn’t wash with a lot of people :stuck_out_tongue:


So, round two, this is what I’ve got.

https://book.cakephp.org/4/en/tutorials-and-examples/cms/articles-controller.html#adding-articles

The opening “<?php” is missing in the quoted file - its easily fixed, and I only mention this as I have now fallen for this twice!!

https://book.cakephp.org/4/en/tutorials-and-examples/cms/tags-and-users.html#finding-articles-by-tags

The routes.php file is different from the tut with chunks of comments and using the object operator ( → ) instead of the scope resolution operator ( :: ). A minor difference, just making you aware in case it’s relevant.
And in keeping with the newer approach the code added should now be: -
// Add this
// New route we’re adding for our tagged action.
// The trailing * tells CakePHP that this action has
// passed parameters.
$routes->scope(‘/articles’, function (RouteBuilder $routes) {
$routes->connect(‘/tagged/*’, [‘controller’ => ‘Articles’, ‘action’ => ‘tags’]);
});


For consistency at https://book.cakephp.org/4/en/tutorials-and-examples/cms/tags-and-users.html#creating-the-view is missing the first line comment containing the filename: -


Changed formatting of the -> in the code to follow the same carriage return structure as what was previously there (for readability)
https://book.cakephp.org/4/en/tutorials-and-examples/cms/tags-and-users.html#auto-populating-the-tag-string

Should the templates folder be in the src folder? Because that is where it is on cms github. Also it has file extension .ctp whereas we are using .php. In fact, the github is very out of date. Missing the tag list in article view, different object / class uses, field names, etc! I know you’re aware of this, it’s more of a reminder for myself that it’s not compatible to the tute.

Is there an easy way to tell CakePHP that the index for editing articles is the slug, and not the id? For instance when viewing a tag which has been used in an article, the bake view shows related articles with View / Edit & Delete controls, but they link to the id and not the slug. The tag view can be edited to correct that, but I was just wondering if there’s an override setting which knows to use the slug field?
Or another option would be to redirect an attempted view of the article, if not found then to search by id. Now the slug & id should never overlap (in this instance) as we validate the title to be at least 10 characters, and it’s unlikely our CMS will have 1000000000 posts!

https://book.cakephp.org/4/en/tutorials-and-examples/cms/authentication.html#adding-password-hashing

bin/cake bake all users
This was already [sort of] done here: https://book.cakephp.org/4/en/tutorials-and-examples/cms/tags-and-users.html
So we just need to be reassured to overwrite the existing files.

Change file identifier of login.php https://book.cakephp.org/4/en/tutorials-and-examples/cms/authentication.html#adding-login
from: -

// in /templates/Users/login.php

to: -

<!-- in /templates/Users/login.php --> 

As we’re not in php code here.



https://book.cakephp.org/4/en/tutorials-and-examples/cms/authentication.html#enabling-registrations

Let them know the code change is in beforeFilter() function.
Side question, how can I add my home page to the acceptable list? I.E. /templates/Pages/home.php




I still cannot get through the authorization page. After completing this section: -

https://book.cakephp.org/4/en/tutorials-and-examples/cms/authorization.html#enabling-the-authorization-plugin

The webpage now shows: -


Should “$middleware->add(new AuthorizationMiddleware($this));” be “$middlewareQueue->add(new AuthorizationMiddleware($this));” ?
Again due to the crash it makes no difference, so I can’t tell.

The github source does not implement the Authorization section.
And I cannot progress any further due to the next error…

https://book.cakephp.org/4/en/tutorials-and-examples/cms/authorization.html#creating-our-first-policy

The bake policy command is missing!
Would it be something like “bin/cake bake article policy” ?
Anyway, bake crashes with the same error as the webpage produces above, so I can’t guess.
Also, this is now fatal. I cannot progress any further on the tutorial, and have came unstuck at the exact same place I did last time!




Having stopped there here is a couple of suggestions from as far as I did get.

A minor tidiness is on the login.php I added this line at the bottom: -

<h3><?= $this->Html->link("Add User", ['action' => 'add']) ?></h3>

For completeness I knocked up a home screen, /templates/Pages/mine.php : -
<!-- in /templates/Pages/mine.php --> 
<h1><u>
<a href="articles">Articles</a><br>
<a href="users">Users</a><br>
<a href="tags">Tags</a><br>
<a href="users/logout">Logout</a><br>
</u></h1>

and changed the routes.php from ‘Home’ to ‘Mine’ in $builder->connect(‘/’, …


I have to state though I specifically chose CakePHP due to its Authentication and Authorization ; so I’m a bit sad as there’s where it came unstuck.

Thanks for your help so far.
Please let me know if the issue is with me, or with the tut - I would like to see this working.

Cheers
Jonathan

Fatal error: Declaration of App\Application::getAuthorizationService(Psr\Http\Message\ServerRequestInterface $request, Psr\Http\Message\ResponseInterface $response) must be compatible with Authorization\AuthorizationServiceProviderInterface::getAuthorizationService(Psr\Http\Message\ServerRequestInterface $request): Authorization\AuthorizationServiceInterface in F:\webdev\cms\src\Application.php on line 129

Signature of Application::getAuthorizationService() in code block has been updated to fix the error.

Should “$middleware->add(new AuthorizationMiddleware($this));” be “$middlewareQueue->add(new AuthorizationMiddleware($this));” ?

Yes, fixed.

Would it be something like “bin/cake bake article policy” ?

The proper command is now shown in the tutorial

P.S. For quick support you can join cakephp’s slack / IRC channel.

{More newbie post butchering to avoid the 2 link limit, again apologies for horrible layout this causes.}

Thanks, I’ll use IRC once I got the basics, only because I don’t want immediate answers, I am playing / experimenting / learning.
[And I feel if I miss the basics for whatever reason this thread may be of use, even if only for myself later!]

Meanwhile, round 3.

The “book” entry on authorization:*2.0 has here https://book.cakephp.org/authorization/2/en/index.html#installation
Load the plugin by adding the following statement in your project’s src/Application.php:
$this->addPlugin('Authorization');
But that is not mentioned in the tute. Is this line needed?


https://book.cakephp.org/4/en/tutorials-and-examples/cms/authorization.html#enabling-the-authorization-plugin
Declaration in src/Application.php should be: -
public function getAuthorizationService(ServerRequestInterface $request): AuthorizationServiceInterface
(I see the tute was updated to reflect this, but as it took me ages to solve it myself I am still posting about it, hehe)


https://book.cakephp.org/4/en/tutorials-and-examples/cms/authorization.html#creating-our-first-policy
The missing bake command [for me] is: -
bin/cake bake policy Article
I tried the new one in the tute of “bin/cake bake policy --type entity Article” and it said “Error: Unknown option type.”
(I also a “composer update” in case I had an old version, no difference.)


https://book.cakephp.org/4/en/tutorials-and-examples/cms/authorization.html#creating-our-first-policy
Does this policy have the wrong namespace, or is it supposed to be TestApp\Policy?
Also, does the file naming convention change for policies, where it uses the singular ArticlePolicy instead of ArticlesPolicy?


https://book.cakephp.org/4/en/tutorials-and-examples/cms/authorization.html#fixing-the-add-edit-actions
in src/Controller/ArticlesController.php “public function edit($slug)” is missing lines: -
// Get a list of tags.
$tags = $this->Articles->Tags->find(‘list’);
// Set tags to the view context
$this->set(‘tags’, $tags);


https://book.cakephp.org/4/en/tutorials-and-examples/cms/authorization.html#fixing-the-add-edit-actions
These lines can also be removed from template/Articles/add.php: -
// Hard code the user for now.
echo $this->Form->control(‘user_id’, [‘type’ => ‘hidden’, ‘value’ => 1]);


Now my last problem is simply this. Everything besides those with specific policies gives the error: -

Which happens on /articles /users /tags and / itself - everything which doesn’t have a specific policy set (so /article/add does work).
So there must be a setting which allows view access regardless? I can’t imagine that I need to create a policy for every single entity and action!


Thanks again!
Also, if you prefer I no longer post here then I will move on to IRC!!

Can you make an issue for the broken tutorial sections?

I actually started there, but felt it was presuptious to raise an issue on a technology I know nothing about. Besides, half the things I came across were my own fault, from not reading the tute correctly, or simply not applying the thinking I should have.

Also, I had several questions which weren’t directly related to the tutorial, but I would still like to know the answers to. In fact, once the cms example is running, I’ll revisit those as a list in a subsequent post.

Once I feel I know what I am talking about, I will note any further actual errors on a github issue. Thank you for the suggestion.

Hey @Jawfin thank you for the feedback on the tutorial. I’ve put up pull requests to address more items in your second round of feedback and also sync the tutorial repository with the tutorial :slight_smile:

Howdy!

I’ve gone through the tute at least 4 times now, I’ve spotted a few bugs but because I’m on the clock I haven’t posted github fixes. Besides, the minor debugging is part of the learning process anyway!

In my OP I asked how to access the home page without flagging the Authorization exception. This is my solution, but please, can someone show me the correct way as this is such an ugly hack.
In \src\Controller\PagesController.php I edited the display() function, and added these lines: -

    public function display(...$path): ?Response
    {
        if (!$path) {
            return $this->redirect('/');
        }
        //My new lines here...
        if ($path[0] === 'home') {
            $this->Authorization->skipAuthorization();
        }

lol…

Ok, so, this is what I tried which I thought should have worked, but I’m still bending my brain around the structures. In the same PageController.php I tried adding this function: -

    public function home()
    {
        $this->Authorization->skipAuthorization();
    }

But it didn’t seem to do anything.

(EDIT: Turns out that didn’t work anyway, it only works after I’ve logged in, so I’m still looking for how to allow access to the home page.)

(EDIT:EDIT: I also tried adding ‘home’ and ‘display’ to the addUnauthenticatedActions in the beforeFilter in AppController.php, and I created a PagePolicy.php setting all results to true as well as adding functions canDisplay() & canHome() returning true too - I’ve given up. Surely it can’t be this hard to have the homepage not fire a The request to / did not apply any authorization checks.)

I also mentioned in the OP it would be nice to actually have a home page - so for anyone who is testing they can try mine. This goes in \templates\Pages\home.php and again it is a hack, it’s not using CakePHP, its just a bunch of links - so if someone could post the proper way of doing this, that would be awesome. My mashup: -

<h1><u>
<a href="articles">Articles</a><br>
<a href="users">Users</a><br>
<a href="tags">Tags</a><br>
<a href="users/logout">Logout</a><br>
</u></h1>

And for a bonus, in the \src\Controller\UserController.php logout() change
return $this->redirect(['controller' => 'Users', 'action' => 'login']);
to
return $this->redirect(['controller' => 'Pages', 'action' => 'home']);
:slight_smile:

I’ve looked at CakePHP long enough now to decide I’m in for the long haul - I tend to be rather exacting so I apologise to everyone in advance for my fastidiousness.

I need to post one more time, instead of editing yet again. Solution is in AppController in beforeFilter add ‘display’ to the addUnauthenticatedActions list, and in PagesController just put $this->Authorization->skipAuthorization(); as the first line of function display() and it would seem a PagePolicy is not required. I think I got the logic now, penny dropped.

But for heaven’s sake please someone correct me if I’m wrong, hehe.

2 Likes

Due to various technical issue we still don’t have the API docs for v4 available sorry about that.

@ADmad Where is the technical issue being tracked on GitHub? I’d like to help if I can?