/**
  * Displays the list of existing job queues.
  * 
  * @param   array   $arguments    (optional)
  * @param   array   $options      (optional)
  */
 protected function execute($arguments = array(), $options = array())
 {
     $project = ProjectConfiguration::getActive();
     $root = $project->getRootDir();
     // Setting basic vars..
     $model = $arguments['route_or_model'];
     $name = strtolower(preg_replace(array('/([A-Z]+)([A-Z][a-z])/', '/([a-z\\d])([A-Z])/'), '\\1_\\2', $model));
     $module = $options['module'] ? $options['module'] : $name;
     $this->path = $root . "/apps/" . $arguments["application"] . "/modules/" . $module;
     // Theme is always AppFlower..
     $options["theme"] = "appFlower";
     if (!is_dir($this->path)) {
         // Reading Schema (from all plugins and the app)
         if (!file_exists($root . "/config/schema.yml")) {
             throw new sfCommandException("Couldn't read schema.yml!");
         }
         $this->schema = SchemaUtil::readSchema(true);
         // Check if routing is used, and determine the model name.
         $route = $this->getRouteFromName($model);
         if (false !== $route) {
             $options = $route->getOptions();
             $model = $options["model"];
         }
         // Generate CRUD..
         if (!$options["no-forms"]) {
             $classes = array("sfPropelBuildFormsTask" => "Generating Forms & Filters..", "sfPropelBuildFiltersTask" => "");
             foreach ($classes as $class => $message) {
                 $this->runOtherTask(array($class, $message));
             }
         }
         $this->logBlock("Generating CRUD for " . $arguments["application"] . "/" . $module, "QUESTION");
         // is it a model class name
         if (!class_exists($model)) {
             throw new sfCommandException(sprintf('The route "%s" does not exist and there is no "%s" class.', $model, $model));
         }
         $r = new ReflectionClass($model);
         if (!$r->isSubclassOf('BaseObject')) {
             throw new sfCommandException(sprintf('"%s" is not a Propel class.', $model));
         }
         $arguments["model"] = $model;
         $arguments["module"] = $module;
         $this->generate($arguments, $options);
         $this->logBlock("Generating Widget XML data..", "QUESTION");
         // Get schema data..
         $data = SchemaUtil::getSchemaDataForModel($model, $this->schema);
         // Generate widget XMLs..
         $this->generateWidgets($data, $model, $module);
         $this->logBlock("Clearing cache..", "QUESTION");
         $this->runOtherTask(array("sfCacheClearTask", null));
         $this->logBlock("All done!", "QUESTION");
         $this->logSection("Module has been successfuly initialized!", null, null, "INFO");
         $this->logSection("Please fill apps/" . $arguments["application"] . "/modules/" . $module . "/config/generator.yml to fine-tune..", null, null, "INFO");
     } else {
         throw new sfCommandException("Module \"" . $module . "\" alerady exists! Please fill generator.yml!");
     }
 }
 private function buildXmlDocument($module, $view)
 {
     $default = true;
     $actionInstance = $this->context->getActionStack()->getLastEntry()->getActionInstance();
     $file = $this->root . "/apps/" . $this->application . "/modules/" . $module . "/config/generator.yml";
     if (!file_exists($file)) {
         throw new XmlParserException("Couldn't read " . $file);
     }
     $current = sfYaml::load(file_get_contents($file));
     $schema = SchemaUtil::readSchema(true);
     // Default generator.yml, nothing to do..
     $params = $current["generator"]["param"];
     $default_actions = isset($params["default_actions"]) && $params["default_actions"] !== false;
     $pager = isset($params["pager"]) && $params["pager"] !== false;
     $table = SchemaUtil::getSchemaDataForModel($params["model_class"], $schema);
     // Determine primary key
     if (($pk = SchemaUtil::getPrimaryKey($table)) === false) {
         throw new XmlParserException("Couldn't determine primary key of " . $module . "!");
     }
     $data = $params["config"];
     unset($params["config"]);
     foreach ($data as $section => $value) {
         if ($value) {
             $default = false;
             break;
         }
     }
     if ($view == "list") {
         $fieldname = "column";
         $section = "list";
     } else {
         if ($view == "edit") {
             $fieldname = "field";
             $section = "form";
         } else {
             throw new XmlParserException("Invalid view type!");
         }
     }
     if (isset($data[$section]["credentials"])) {
         if ($this->user->hasCredential($data[$section]["credentials"]) === false) {
             $actionInstance->forward("pages", "insufficientCredentials");
             return false;
         }
     }
     if (!$default) {
         $xpath = $this->getXPath();
         if (isset($data[$section]["scripts"]) && $data[$section]["scripts"] !== false) {
             $new = $this->document->createElementNS($this->namespace, "scripts");
             $new->nodeValue = implode(",", $data[$section]["scripts"]);
             $title = $xpath->evaluate("//i:title")->item(0);
             $this->document->documentElement->insertBefore($new, $title);
         }
         // Fields and columns
         $fields = $data["fields"];
         if (isset($data[$section]["fields"])) {
             foreach ($data[$section]["fields"] as $key => $value) {
                 foreach ($value as $attr => $attrvalue) {
                     $fields[$key][$attr] = $attrvalue;
                 }
             }
         }
         // Add primary key if not listed in yml..
         if (!isset($fields[$pk])) {
             $fields[$pk] = array("type" => "hidden");
         }
         // Rearrange columns for lists and remove non-visible columns from edit view..
         if (isset($data[$section]["display"])) {
             if ($fieldname == "column") {
                 $tmp = array();
                 foreach ($data[$section]["display"] as $colname) {
                     $tmp[$colname] = $fields[$colname];
                 }
                 foreach ($fields as $colname => $col) {
                     if (!array_key_exists($colname, $tmp)) {
                         $col["hidden"] = "true";
                         $tmp[$colname] = $col;
                     }
                 }
                 $fields = $tmp;
             } else {
                 foreach ($fields as $colname => $col) {
                     $found = false;
                     foreach ($data[$section]["display"] as $set) {
                         foreach ($set as $ref) {
                             if ($ref == $colname || $ref == "-" . $colname) {
                                 $found = true;
                                 break;
                             }
                         }
                     }
                     if (!$found && $colname != $pk) {
                         unset($fields[$colname]);
                     }
                 }
             }
         }
         // Custom values
         if ($fieldname == "field") {
             // Save value tags for later use..
             $tmp = $xpath->evaluate("//i:fields/i:field/i:value");
             foreach ($tmp as $value) {
                 $this->fieldvalues[$value->parentNode->getAttribute("name")] = $value->cloneNode(true);
             }
             if (isset($data[$section]["values"])) {
                 foreach ($data[$section]["values"] as $fname => $value) {
                     $params = array();
                     if (isset($fields[$fname]["renderer"])) {
                         $value = $fields[$fname]["renderer"];
                     }
                     if (isset($fields[$fname]["renderer_arguments"])) {
                         $params = $fields[$fname]["renderer_arguments"];
                     }
                     $this->fieldvalues[$fname] = self::createValueElement($value, $this->document, $this->namespace, $params);
                 }
             }
         }
         // Fields / columns and inheritance..
         $this->parseYmlFields($fields, $fieldname, $table, $pager);
         // Validator and handlers..
         if ($fieldname == "field") {
             $this->parseYmlFieldChildren($data[$section]);
         }
         // Title, max_per_page
         $this->parseYmlSimpleElements($data[$section], array(array("title", "//i:title"), array("max_per_page", "//i:params/i:param[@name='maxperpage']")));
         // Display and hide..
         $key = false;
         if (isset($data[$section]["display"])) {
             $key = "display";
         } else {
             if (isset($data[$section]["hide"])) {
                 $key = "hide";
             }
         }
         if ($key != "parseYml") {
             call_user_func_array(array($this, "parseYml" . ucfirst($key)), array($data[$section][$key], $view, $params));
         }
         // Actions, rowactions and moreactions..
         $this->parseYmlActions($data[$section], $default_actions);
         // Default sorting..
         if (isset($data[$section]["sort"])) {
             $field = $xpath->evaluate("//i:fields/i:column[@name='" . $data[$section]["sort"][0] . "']");
             if (!$field->length) {
                 throw new XmlParserException("Invalid field name");
             }
             $field = $field->item(0);
             $field->setAttribute("sort", strtoupper($data[$section]["sort"][1]));
         }
     }
     //$this->document->save("/tmp/12.xml");
 }