Jump to content
Larry Ullman's Book Forums

Struggling With Parameter Handling Of Controllers And Views (Newbie)


boris.halter
 Share

Recommended Posts

Hello together,

maybe I don't see the forest for the trees, but I'm struggling with parameter handling of controllers and views...

To start with Yii, MVC and RBAC I tried do build a simple page (something like http://mysite.domain.com/authitem) that draws the parent->childhood relations of my AuthItems using the prebuild Yii demo app.

I manualy installed the PEAR extension "Image_Graphviz" (pear install ...) to draw the graphs. I created the model with Giix and edited the AuthItemController.php manualy (I copied the stuff from other controllers ;)

Accessing the tables, building the graph and "draw" it in the browser went fine with only one bad thing: I did it all in the controller (just to be sure Graphviz works). And it does, it works great!

After that I tried to do it the MVC style and modified .../views/authItem/index.php. Instead of doing it directly with $graph->image(), I switched to $this->render() in AuthItemController::actionIndex() (please have a look on the code snippets below). But this led me into a XML error message shown in the browser:

------------------------XML Error------------------------
XML-Verarbeitungsfehler: XML- oder Text-Deklaration nicht am Beginn der Entität
Adresse: http://localhost/stable/authItem
Zeile Nr. 49, Spalte 1:<?xml version="1.0" encoding="UTF-8" standalone="no"?>
^

------------------------XML Error------------------------

This means translated something like: XML or text declaration not at start of entitiy (row 49, col 1)


What did I wrong?

Does the view not have access to the $graph instance forwarded from the controller? I thought this will be done with $this->render('index', array( 'graph' => $graph));?

Regards,
Boris


My code:

------------------------[controllers/AuthItemController.php]------------------------
<?php
require_once 'Image/GraphViz.php';

class AuthItemController extends GxController {

    public function filters() {
        //Nothing special
    }

    public function accessRules() {
        //Nothing special
    }

    // Here it goes...
    public function actionIndex() {

        $graph = new Image_GraphViz();

        // Get the data from table AuthItem
        $cmd = Yii::app()->db->createCommand();
        $cmd->select = 'name, type, bizrule';
        $cmd->from = 'AuthItem';
        $result = $cmd->query();

        // Build the graph nodes
        foreach ($result as $row) {
            switch ($row['type']) {
                case 0:  $shape = 'box';   break;
                case 1:  $shape = 'box';   break;
                case 2:  $shape = 'house'; break;
                default: $shape = 'box';
            }

            $graph->addNode(
                $row['name'],
                array(
                    'label' => $row['name'],
                    'shape' => $shape,
                )
            );
        }

        // Get the data from table AuthItemChild
        $cmd = Yii::app()->db->createCommand();
        $cmd->select = 'parent, child';
        $cmd->from = 'AuthItemChild';
        $result = $cmd->query();

        // Build the graph egdes
        foreach ($result as $row) {
            $graph->addEdge(
                array(
                    $row['parent'] => $row['child']
                )
            );
        }

    // "Drawing" the graph in the browser without MVC. Works fine.
        // $graph->image();

    $this->render('index', array( 'graph' => $graph));
    }
}
?>

------------------------[controllers/AuthItemController.php]------------------------



------------------------[views/authItem/index.php]------------------------
<?php
/* @var $graph GrahpViz Instance */

[...]

?>

<h1><?php echo GxHtml::encode(AuthItem::label(2)); ?></h1>

<?php $graph->image(); ?>
[...]

------------------------[views/authItem/index.php]------------------------
 

Link to comment
Share on other sites

$this->render('index', array( 'graph' => $graph));

This statement is correct for passing standard, variables and objects.

 

Just one thing i want to say though is all that database access code in the controller is a no no anyway you need to be pushing this into some kind of model or a separate file. It looks like some kind of connection was lost with the variable when you pasted it to the views file. I think what you need to do is create a model function and then access this directly from the views file, rather than passing the $graph object from the controller to the views file.

 

Any way this was just a suggestion i haven't used those extensions you are using there so i can't give you the correct answer but something to try, hope it will help in reaching your solution.

Link to comment
Share on other sites

SOLVED.

 

It was more a layer 8 error, than a technical one... :angry:

 

I just called the wrong function of Graphviz to generate a graph. The function graphviz->image() generates its own html5 code with an inline  svg-"picture" between the full set of html headers (doctype, html, body, etc.). To use that as $content in a view file was a very bad idea.

 

I used graphviz->fetch() instead, that just returns the rendered "graphic data" (<svg ... </svg>).

 

This is an example of what will be rendered by grpahviz->fetch():

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="190">
   <polygon points="100,10 40,180 190,60 10,60 160,180"
   style="fill:lime;stroke:purple;stroke-width:5;fill-rule:evenodd;">
</svg>

 

 

Btw.: is this a more "MVC style" code? Did I get it?

Is there a more secure/sophistic way than just to echo the data?

 

 

Controller:

------------------------[controllers/AuthItemController.php]------------------------

[...]
    public function actionIndex() {
        $model = new AuthItem;
        $this->render('index', array(
            'model' => $model));
    }

[...]

------------------------[controllers/AuthItemController.php]------------------------

 

 

 

View:

------------------------[views/authItem/index.php]------------------------

[...]

<h1><?php echo GxHtml::encode(AuthItem::label(2)); ?></h1>

<?php echo $model->showGraph(); ?>

[...]

------------------------[views/authItem/index.php]------------------------

 

 

 

Model:

------------------------[models/authItem.php]------------------------

<?php

require_once 'Image/GraphViz.php';

Yii::import('application.models._base.BaseAuthItem');

class AuthItem extends BaseAuthItem
{
    public static function model($className=__CLASS__) {
        return parent::model($className);
    }

    public function showGraph() {

        $graph = new Image_GraphViz();

        $cmd = Yii::app()->db->createCommand();
        $cmd->select = 'name, type, bizrule';
        $cmd->from = 'AuthItem';
        $result = $cmd->query();

        foreach ($result as $row) {
            switch ($row['type']) {
                case 0:  $shape = 'box';   break;
                case 1:  $shape = 'box';   break;
                case 2:  $shape = 'house'; break;
                default: $shape = 'box';
            }

            $graph->addNode(
                $row['name'],
                array(
                    'label' => $row['name'],
                    'shape' => $shape,
                )
            );
        }

        $cmd = Yii::app()->db->createCommand();
        $cmd->select = 'parent, child';
        $cmd->from = 'AuthItemChild';
        $result = $cmd->query();

        foreach ($result as $row) {
            $graph->addEdge(
                array(
                    $row['parent'] => $row['child']
                )
            );
        }
        return $graph->fetch();
    }

}

------------------------[models/authItem.php]------------------------

Link to comment
Share on other sites

 Share

×
×
  • Create New...