tags:

views:

317

answers:

1

I am using Symfony 1.2.9 (with Propel ORM) to create a website. I have started using the admin generator to implement the admin functionality. I am having all manner of problems getting the admin manager to display an object (blog) that has one 1:N relation (blogposts) and one N:M relationship (blogroll).

This is proving to be far more difficult than I had ever imagined (and I daresay, than it needs to be). I have already spent two days on this problem and have not made much progress. I am trying to generate admin functionality for a blog.

I have posted an abridged version of my schema here. Hopefully it will help clarify the problem I am having (maybe I am not explaining the problem clearly enough - but hopefully, the schema should clarify the problem I am facing, and what I'm trying to do).

A blog has 0 to 1 blog rolls, 0 to N blog posts attached to it. Each blog post has 0 to M comments attached to it. Currently, I can view a list of blogs. But I want to add 2 interactions (or links) that can make me:

  1. view the blogroll (which is a list of blogs attached to the blog)
  2. view the list of blogposts attached to a blog.

When a blogpost list is shown, I want link to show a link (same functionality as before), that allows me to show the list of comments for the selected blogpost.

I am sure I am not the first (or only) person that has tried to do this before. Am I going about it the wrong way, is there a better (i.e. more intuitie for the user) way of displaying and performing CRUD on objects with such relationships?. Can anyone out there help?

+2  A: 

Why don't you do it as you have proposed by yourself in your other question.

(This is again for Doctrine but for Propel it should be similar).

Create an object action in your generator.yml:

list:
    object_actions:
      bloglist: {label: Bloglist}

Then in your actions.class.php you have to add a function:

public function executeListBloglist(sfWebRequest $request) {
    $blog = $this->getRoute()->getObject();

    // retrieve the blogposts via a PEER method (I don't have any clue about Propel ;))
    $this->blogposts = however.you.get.the.blogposts();
}

Then create a template bloglistSuccess.php where you show the posts.

Or, you can redirect or forward to the admin module for the blogposts if you have such a module. There you have probably to override the list action to accept the ID parameter of the blog and extend the query to filter posts by this blog id.
There is nothing wrong in doing a redirect or forward, it is not a hack ;)


Edit after comment:

I would also suggest that you forward the request.
No you don't have to change the routing you can just append the parameter like you suggested.

For overriding I reconsidered that it would be better if you override the buildQuery method (again). (I can't remember how this method was called with Propel, I hope you get what I mean).

So it would look like this:

class blogpostAdminActions extends autoBlogpostAdminActions 
{

  //...

  protected function buildQuery()
  {
     $query = parent::buildQuery();

     $request = $this->getRequest(); // <- I am not sure about this method call but there is one that gives you the webRequest.

     if ($request->hasParamter('blog_id'))
     {
        $query->andWhere('blog_id = ?', $request->getParameter('blog_id'));
     }

     return $query;
  }
}

Of course you have to change this to Propel criteria, but I assume you can do that ;)
Hope this helps you.

Felix Kling
Hi Felix, thanks for your reassurances about the forwards/redirects not being a hack. I come from a desktop C++ environment, so sometimes am too rigid in my thinking ;)Anyway, back to your proferred soln, I prefer to forward to the module generated by the admin gen, bcos it has a filter section etc. I think the missing link is just what you suggested. I have overriden the buildCriteria() method like you suggested in a previous post, and I am setting the blog_id there (retrieved from a session - bad!). I can override the list action, but could you please clarify what you mean by:
Stick it to THE MAN
i).override the list action to accept the ID parameter of the blog - Do I have to change the routing for the list to take a blog_id parameter, or can I simply append a '?blog_id=$vlog_id to the url, and then use $request->getParameter('blog_id') in the overriden list action?ii). extend the query to filter posts by this blog id.I would be grateful if you could send me a snippet (via pastebin) that demonstrates what you mean by (i) and (ii). I should be able to implement the functionality after that I think. Once again, thanks for your help.
Stick it to THE MAN
I tried forwarding and got an error:return $this->forward('blgpostadmin', "index?blog_id=$blog_idAction "blgpostadmin/indexblog_id3user_id3" does not exist.??!
Stick it to THE MAN
It seems the forward() method does not accept parameters?
Stick it to THE MAN
The way I got this to work in the past was to use user session variables. The problem with that though is that it works for showing the list - however, when you come to create a new blogpost, we should already have the blog_id set - however, the blog post form allows the user to select from a list of all available blogs. This is incorrect, since the list was originally restricted to a particular blog id. I tried to override the new action, but I coudn't find a way to get to the blog_id. I suppose I could use the session_id, but that is begining to feel a lot like a global variable ...
Stick it to THE MAN
I have overriden the buildQuery() method and the list is showing the restricted records. Is there anyway to restrict the filter on the blog_id field (worse case scenario, I will simply remove that field from the form)
Stick it to THE MAN
Yeah session is not the best solution... You can use the parameter holder of the request object to forward parameters: `$this->getRequest()->setParameter('blog_id', $blog_id);` and then forward normally with `$this->forward('blgpostadmin', 'index')`. I hope this works.
Felix Kling
For the filtering, I have no clue.....yet ;)
Felix Kling
Ah thanks, atleast thats one less problem.I am overriding the New action for the blogpost, so that the new form has the blog_id and author_id set (so I can remove them from the display. I tried this (http://pastebin.com/m37afab67) and found that I could not set the form fields. Any idea on how I can somehow change the values. Basically, I want to remove the blog_id and the author_id from the form, but it wont validate if they are not populated ...
Stick it to THE MAN
Mmh you should create a new form that inherits from the auto generated form and change the widgets from input fields to hidden fields. That should work. See the 'Jobeet' tutorial for dealing with forms.
Felix Kling