How to access relationship data in groupgridview with extraRowColumns - yii

The Database Tables:
project_master (id, project_name)
task_master (id, task_name, project_id)
Relationship in the TaskMaster Model:
TaskMaster.php
class TaskMaster extends CActiveRecord
{
/**
* #return array relational rules.
*/
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'ProjectsRpl' => array(self::BELONGS_TO, 'Projects', 'project_id'),
);
}
}
Following GroupGridView view file:
Task.php
$this->widget('ext.groupgridview.GroupGridView', array(
'id' => 'Customer-grid',
'dataProvider' => $modelCustomer->searchCustomer(),
//'mergeColumns' => 'project_id',
'extraRowColumns' => array('ProjectsRpl.project_name'),
'extraRowPos' => 'above',
'afterAjaxUpdate' => 'function(){}',
'columns'=>$columns,
));
GroupGridView reference site.
Getting the following errors:
CException: Column or attribute "ProjectsRpl.project_name" not found!

Only one change in Task.php file.
$this->widget('ext.groupgridview.GroupGridView', array(
'id' => 'Customer-grid',
'dataProvider' => $model->search(),
//'mergeColumns' => 'project_id',
'extraRowColumns' => array('project_id'),
'extraRowPos' => 'above',
'extraRowExpression' => '"<b style=\"color: black\">".$data->ProjectsRpl->project_name."</b>"',
'afterAjaxUpdate' => 'function(){}',
'ajaxUrl' => Yii::app()->createUrl('customer/index'),
'ajaxUpdate' => true,
'enablePagination' => true,
"summaryText" => true,
'enableSorting' => FALSE,
'columns'=>$columns,
));

Related

F3 Cortex and Many to Many relation

I'm building a simple app using F3 and Cortex but I'm running in some problems trying to create a simple Many to Many relation. Its just two tables (and a third, from the relation), the tables already exist and have some data:
class User extends \DB\Cortex {
protected
$fieldConf = array(
'name' => array (
'type' => 'VARCHAR128',
'nullable' => false,
'required' => true,
),
'email' => array (
'type' => 'VARCHAR256',
'nullable' => false,
'required' => true,
),
'password' => array (
'type' => 'VARCHAR128',
'nullable' => false,
'required' => true,
),
// 'groups' => array(
// 'has-many' => array('Group', 'group_id', 'user_has_group')
// )
),
$db = 'db',
$table = 'user';
}
and
class Group extends \DB\Cortex {
protected
$fieldConf = array(
'name' => array(
'type' => 'VARCHAR128',
'nullable' => false,
'required' => true,
),
'description' => array(
'type' => 'VARCHAR128',
'nullable' => false,
'required' => true,
),
// 'users' => array(
// 'has-many' => array('User', 'user_id', 'user_has_group')
// )
),
$db = 'db',
$table = 'group';
}
accourind with this model of the database
But if I remove those comment marks, I get a strange error while acessing anything:
Internal Server Error
No valid DB Connection given.
And on refresh:
Internal Server Error
Fatal error: Leaked 1 hashtable iterators
It looks silly, but I searched all over and spent the better part of a whole day, and still can't seem to make it work.

How to enable eager loading on a association in phpactiverecord?

I have an phpactiverecord Model "Category". This Model has a self-referential has_many association, and two has_one associations to another Model.
class Category extends Model {
static $table_name = 'categories';
static $has_many = array(
array(
'child_categories',
'class_name' => 'Category',
'primary_key' => 'categories_id',
'foreign_key' => 'parent_id'
)
);
static $has_one = array(
array(
'german_description',
'class_name' => 'CategoryDescription',
'primary_key' => 'categories_id',
'foreign_key' => 'categories_id',
'conditions' => 'language_id = 2'
),
array(
'english_description',
'class_name' => 'CategoryDescription',
'primary_key' => 'categories_id',
'foreign_key' => 'categories_id',
'conditions' => 'language_id = 1'
)
);
}
I can eager-load the has_one associations when I find Category, this works without any problem:
$category = ActiveRecord\Category::find(
$category_id,
array(
'include' => array( 'german_description', 'english_description' )
)
);
My problem is: When I iterate through all of a category's child-categories, and access the child-categories' has-one associations...
foreach( $category->child_categories as $child_category ){
echo $child_category->german_description->categories_name;
}
..then a new query is run every time I do so, becauce the child-category's has-one associations are not eager loaded.
My question is: Is it possible to configure access a categories child-categories in a way that eager-loads the child-categories' has-one associations?

Yii file CFormInputElement won't display unless explicitly marked "safe"

I'm trying to use Form Builder to build a simple file upload prompt. I want to specify the rule for the file to be similar to
array('formFile', 'file', 'allowEmpty' => false, 'types' => 'html'),
but something is wrong. The file upload element only appears if I explicitly mark the element as 'safe' (and remove the 'file' rule). What am I missing?
models/UploadForm.php
class UploadForm extends CFormModel
{
public $year;
public $formFile;
public function rules ()
{
return array(
array('year', 'required'),
array('year', 'date', 'format'=>'yyyy'),
// array('formFile', 'safe'),
array('formFile', 'file', 'allowEmpty' => false, 'types' => 'html'),
);
}
static public function getYearOptions () {...}
}
views/extranet/uploadForm.php
return array(
'title' => 'Select year',
'method' => 'post',
'enctype' => 'multipart/form-data',
'elements' => array(
'year' => array(
'type' => 'dropdownlist',
'items' => UploadForm::getYearOptions(),
),
'formFile' => array(
'type' => 'file',
'label' => 'form source file',
),
),
'buttons' => array(
'upload' => array(
'type' => 'submit',
'label' => 'upload',
),
),
);
controllers/ExtranetController.php
class ExtranetController extends CController
{
public function actionIndex ()
{
$form = new CForm('application.views.extranet.uploadForm', new UploadForm());
if ($form->submitted('upload') && $form->validate()) {...}
$this->render('index', array('form' => $form));
}
}
The reason for this is very simple.
The form builder only renders input elements which are considered safe (I.E. have a validation rule). What you have done is perfectly fine, except CFileValidator isn't "safe" by default, whereas other validators are safe.
The quickest way to solve this is the following:
// In your model::rules() function
return array(
array('formFile', 'file', 'allowEmpty' => false, 'types' => 'html', 'safe' => true),
);
Refer to these two links for more information: the CFileValidator#safe documentation, and the Github issue for a problem very similar to yours.

Invalid type given. String expected - Zend Framework 2

Im working on Zend Framework 2 especially with Zend Forms. I have declared a Select dropdown box in
Form:
$selectElement = new Element\Select('selectElement');
$selectElement->setAttribute('title', 'Select a Value')
->setAttribute('id', 'id');
$data = array(
array(
//Fetching the values from database
),
);
$selectElement->setAttribute('multiple', 'multiple')
->setValueOptions($data);
$this->add($selectElement);
InputFilter:
$inputFilter->add($factory->createInput(array(
'name' => 'selectElement',
'required' => false,
'filters' => array(
array(
'name' => 'Int'
),
),
)));
I have used Zend Debug to get the values which are in the selectElement dropbox in this fashion:
$dataSelectElements = $this->getRequest()->getPost('selectElement');
\Zend\Debug\Debug::dump($dataSelectElements);
Debug Result:
array(4) {
[0] => string(2) "20"
[1] => string(2) "22"
[2] => string(2) "23"
[3] => string(2) "75"
}
Basically Im getting the id's from the selectElement form to store it in the database. Right now Im getting a notice and zend form error:
Notice Error:
Notice: Array to string conversion in ..\zendframework\zendframework\library\Zend\Filter\Int.php on line 29
And a form invalid error:
array(1) {
[0] => array(1) {
["selectElement "] => array(1) {
["explodeInvalid"] => string(35) "Invalid type given. String expected"
}
}
}
Is there a solution to over come this problem. Any help would be appreciated.
The Int filter will attempt to make an Integer out of your array of data, which is not going to work.
Previously I've used the Callback filter, which can be used to loop through the data and check if each value is an Int.
For example:
'filters' => array(
array(
'name' => 'Callback',
'options' => array(
'callback' => function($values) {
return array_filter($values, function($value) {
return ((int)$value == $value);
});
}
)
),
),
I did bit differently, something like this
form
class Companyform extends Form
{
public function __construct()
{
// we want to ignore the name passed
parent::__construct('company');
$this->setAttribute ('method', 'post');
$this->setAttribute ('class', 'form-horizontal');
$this->add ( array (
'name' => 'parentID',
'type' => 'Zend\Form\Element\Select',
'attributes' => array(
'id' => 'parentID',
'type' => 'select',
'placeholder' => "Parent Company",
),
'options' => array(
'label' => 'Parent Company'
)
));
$this->add(array(
'name' => 'btnsubmit',
'attributes' => array(
'id' => 'btnsubmit',
'type' => 'submit',
'value' => 'Add',
'class' => 'btn btn-primary'
),
));
}
}
controller
public function addAction()
{
$request = $this->getRequest();
$companyList = $this->_getCompanyList();
$form = new Companyform();
$form->get('parentID')->setAttribute('options',$companyList);
if ($request->isPost())
{
$company = new Company();
$form->setInputFilter($company->getInputFilter());
$form->setData($request->getPost());
if ($form->isvalid())
{
}
}
}
public function _getCompanyList()
{
$companies = $this->Em()->getEntityManager()->getRepository('XXXX\Entity\Company')->findBy(array('isDeleted'=>'0'));
$companyIDList = array();
$companyIDList[0] = "No Parent";
foreach ($companies as $company)
{
$companyIDList[$company->id] = $company->companyName;
}
return $companyIDList;
}
Entity class
protected $inputFilter;
public function setInputFilter(InputFilterInterface $inputFilter)
{
throw new \Exception("Not used");
}
public function getInputFilter()
{
if (!$this->inputFilter) {
$inputFilter = new InputFilter();
$factory = new InputFactory();
$inputFilter->add($factory->createInput(array(
'name' => 'companyName',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min' => 2,
'max' => 255,
),
),
),
)));
$this->inputFilter = $inputFilter;
}
return $this->inputFilter;
}
You may need to add following library in entity
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\Factory as InputFactory;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\InputFilter\InputFilterInterface;
In ZendFramework 2, when you creating a (add) element from your Form file, Check the attribute: inarrayvalidator is true.
$this->add(array(
'name' => 'select_name',
'type' => 'select',
'id' => 'select_name',
'options' => array(
'label' => 'Select Name',
),
'attributes' => array(
'id' => 'select_id',
'inarrayvalidator' => true,
),
));
I hope, this works...

How do I set order by field when using fuelphp orm's has many?

I'm using fuelphp's orm to model my data. How can I control which order my child elements are returned when doing a cascaded find.
For example, here's the example config to attach comments to a post:
protected static $_has_many = array(
'comments' => array(
'key_from' => 'id',
'model_to' => 'Model_Comment',
'key_to' => 'post_id',
'cascade_save' => true,
'cascade_delete' => false,
)
);
How can I say, for example, order the comments by the 'date_entered' field?
Thanks in advance,
David
You can add the order_by clause to the conditions.
protected static $_has_many = array(
'comments' => array(
'key_from' => 'id',
'model_to' => 'Model_Comment',
'key_to' => 'post_id',
'cascade_save' => true,
'cascade_delete' => false,
'conditions' => array(
'order_by' => array(
'field1' => 'DESC',
'field2' => 'ASC',
)
),
),
);
Note that as they are defined in the relation, they are always active and can not be turned off!