Yii create CButton Column for field that exists in another model - php

I'm trying to add the following functionality, however I'm not sure where to start. Any advice, examples, or direction would be greatly appreciated.
I want to add button to the cgridview of the main model in this context. Each of the records available in the cgridview for this model, have a unique attribute called lot for example R3XSEF9
There is another secondary table/model in my database that has records with this same lot attribute. However, this table only has certain records out of all the possible records, sometimes duplicates, and has a set of different attributes.
What I'd like to do is, using the lot attribute, for example lot R3XSEF9 from my cgridview, search the secondary table to see if there is one ore more corresponding rows which contains that same lot R3XSEF9.
If so, I would like the button to be displayed in my CButtonColumn and link to the views for those corresponding models of the secondary table. If not, I would like no button to appear.
Thanks for any help. If any clarification is required, I would be happy to do so.

First of all you need to link tables using "relations" function in model class. If you use FOREIGN KEY constraint in DB relations already filled.
SQL statement:
CREATE TABLE Model1
(
...
FOREIGN KEY(lot) REFERENCES MainModel(lot) ON UPDATE CASCADE ON DELETE RESTRICT,
...
)
Model class:
class MainModel extends CActiveRecord
{
...
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(
'lots' => array(self::HAS_MANY, 'Model2', 'lot'),
);
}
Then you can use custom button column in your grid (view file) like this:
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id' => 'main-grid',
'dataProvider' => $model->search(),
'filter' => $model,
'columns' => array(
...
array(
'class' => 'CButtonColumn',
'template' => '{lots}',
'header' => 'Lots',
'buttons' => array(
'lots' => array(
'label' => 'Lots',
'imageUrl' => Yii::app()->request->baseUrl.'/img/....png',
'url' => 'Yii::app()->createUrl("controller1/lotlistbymainid", array("id" => $data->id))',
'visible' => 'count($data->lots) > 0',
),
),
),
Explanation of button parameters to be passed thru "buttons" array you can find here. Especialy this part:
buttons property
public array $buttons;
the configuration for additional buttons. Each array element specifies a single button which has the following format:
'buttonID' => array(
'label'=>'...', // text label of the button
'url'=>'...', // a PHP expression for generating the URL of the button
'imageUrl'=>'...', // image URL of the button. If not set or false, a text link is used
'options'=>array(...), // HTML options for the button tag
'click'=>'...', // a JS function to be invoked when the button is clicked
'visible'=>'...', // a PHP expression for determining whether the button is visible
)

Related

PrestaShop: Saving Manufacturers

I asked this same question on the official forums but received no response. Not sure if anyone here is experienced with PrestaShop but here is my issue.
I need to add an extra field in the manufacturer edit/add tab, I was able to do this by overriding renderForm in AdminManufacturersController.php like this:
public function renderForm()
{
global $shopOptions;
$this->fields_form_override = array(
array(
'type' => 'checkbox',
'label' => 'Shop',
'name' => 'shop_select',
'desc' => 'Choose The Shops This Manufacturer Applies To',
'values' => array(
'query' => $shopOptions, >> comes from array filled by db query in __construct
'id' => 'id',
'name' => 'name'
),
),
);
return parent::renderForm();
}
This works and I am now trying to find the update and create functions for a manufacturer. When editing the product classes, you can easily spot set functions like setQuantity in StockAvailable.php.
I have ssh access to the server so I was able to dig deeper with grep, to no avail. It seems like it uses some sort of function to auto insert into the database whilst some classes use a plain old execute with a normal query.
Any ideas on where this could be found?
On Prestashop 1.6.x you do not need to amend any function for it to have CRUD functionalities. You just need to add it in :
RenderForm (like you already did)
Add the variable in the manufacturer class (Manufacturer.php) like public $shop_select;
Add it in the public static $definition array in the manufacturer class
Add the column in manufacturer or manufacturer_lang table depending on whether your field is a lang field.
Cheers :)

Yii - Pass model ID into a view from CButtonColumn image

Alright, still new to Yii I am attempting to create a button in a column of CGridView. This button, when clicked, will take the user to the "view.php" page and display the information of the node they clicked on by passing in its ID.
I am frustrated that I cannot figure out how to simply add a link to the image that will direct my users. Here are some snippets of the code I have been working on for the past couple of days.
index.php
<?php echo CHtml::beginForm(); ?>
<?php
$pageSize = Yii::app()->user->getState('pageSize', Yii::app()->params['defaultPageSize']);
$this->widget('zii.widgets.grid.CGridView', array(
'id' => 'nodes-grid',
'dataProvider' => $model->search(),
'filter' => $model,
'columns' => array(
array(
'class' => 'CButtonColumn',
'template' => '{restart}',
'buttons' => array
(
'restart' => array
(
'label'=>'Restart this node',
'imageUrl'=>Yii::app()->baseUrl.'/images/refresh.png',
'options'=>array('id'=>'NB_bounce_Button'),
'url'=>array('view', 'id'=>$model->id),
)
),
),
/* 'id', */
'name',
'url',
'description',
'node_type',
'last_bounced',
//..
NodeBouncerController.php (View action)
/**
* Displays a particular model.
* #param integer $id the ID of the model to be displayed
*/
public function actionView($id) {
$this->render('view', array(
'model' => $this->loadModel($id),
));
}
The button is on the left. (Refresh green arrow)
What am I doing wrong? More specifically, am I using the buttons of CButtonColumn incorrectly? If so, how may I fix this?
My company uses: Yii v1.1.8.r3324
EDIT: [8/10/15]
It seems I may have been overcomplicating it. What I needed was to simply have an image-link that when clicked went to the view for that particular node that was clicked. Well, Gii auto-generates the particular view I needed and the code associated with it (as seen above).
My fix was to do away with the over complicated mess that I had and keep it simple. Use the template already provided for "view" and just alter it to my needs.
Like so:
/* 'id', */
array(
'class'=>'CButtonColumn',
'template'=>'{view}',
'buttons' => array
(
'view' => array
(
'label'=>'Restart this node',
'imageUrl'=>Yii::app()->baseUrl.'/images/refresh.png',
'options'=>array
(
'id'=>'NB_bounce_Button'
)
)
),
),
'name',
'url',
'description',
'node_type',
'last_bounced',
//....
It would be nice to know how to do this manually but I needed something to simply work for now and expand on it later for work.
I think the problem is url of the button. Because you did not include controllerID in the url. You should use this:
'url' => 'Yii::app()->createUrl("nodeBouncer/view", "id"=>$model->id)';
For creating url in yii, usually you should follow this pattern:
contollerID/actionID

Adding associated value by not using foreign key in CakePHP 2

Recently I've started using CakePHP by starting from using Bake to get simple CRUD.
I have one Model called "Contract" which is associated with "Product" and "Customer" as following.
public $belongsTo = array(
'Customer' => array(
'className' => 'Customer',
'foreignKey' => 'customer_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'Product' => array(
'className' => 'Product',
'foreignKey' => 'product_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
Now I wanted to customize the add view (add.ctp) created by Bake by not using select box as an input form for customer_id and product_id. Instead of using select box which shows all the possible name of product/customer that are associated with foreign key I want to use text field so that people can type in one of the field (for example product_code, customer_code) from Product / Customer table and convert it to foreign key to create a row for Contract table. In case there is a chance that no values be found from Customer / Product field I want to skip adding a row to Contract table.
I would like to know if this is possible.
Thank you,
The basic concept is this: Use a JS lib of your choice, guess it's jquery. Watch the text field for changes, on change make an ajax GET request with the value of the text field to a controller / action of your app that returns json. On click on one of the results set the id of the selected record to a hidden field. Done.
If you search Google or Stackoverflow you'll find plenty of examples.

association count within selection

I have a Candidate doctrine entity, this entity has a many to many association to a entity Group
On the index page i show all candidates.
Now i made a form with a ObjectMultiCheckbox object for the Group entity.
After selecting a checkbox and submitting the form i use the doctrine QueryBuilder to only show the candidates that have a association with the selected entity.
This works fine but in the form i'd like to show how many candidates are associated with a certain group.
I can do this using the label_generator option in ObjectMultiSelectCheckbox definition in the fieldset:
namespace MeCandidate\Form;
use Zend\Form\Fieldset;
use Zend\InputFilter\InputFilterProviderInterface;
class SearchFieldset extends Fieldset implements InputFilterProviderInterface
{
public function __construct($objectManager)
{
parent::__construct($name = 'search');
$this->add(
array(
'type' => 'DoctrineModule\Form\Element\ObjectMultiCheckbox',
'name' => 'function',
'attributes' => array(
'class' => 'searchCriteria'
),
'options' => array(
'label' => 'Group',
'object_manager' => $objectManager,
'target_class' => 'MeCandidate\Entity\Group',
'label_generator' => function($targetEntity) {
return ' ' . $targetEntity->getName() . '('. $targetEntity->getCandidates()->count() .')';
},
),
)
);
}
public function getInputFilterSpecification()
{
return array(
array(
'name' => 'group',
'required' => false,
),
);
}
}
This all works as expected.
So when i select Group X it shows all candidates that have a association with Group X.
But now that only a selection of all candidates is shown the number of candidates associated with a certain group is no longer accurate as this shows the total number of candidates associated with the group but i need the number of candidates associated with the group IN the current selection.
I think i can fix it by injecting the current QueryBuilder into the form when creating the form. However i can't find a good way to get the right count.
I hope what i'm trying to do is clear, if not ask me anything.
UPDATE:
I have a working solution, in my Group entity i have a method getCandidateCount it takes a ArrayCollection of the current selection of candidates and checks if a associated candidate is in the selection. I adapted the label_generator function in the fieldset to call getCandidateCount
The problem with this is that after validating the form i have to recreate the form and inject the current selection of candidates into it so i can pass it to the getCandidateCount method inside the label_generator function.
It works but not very elegant so if anybody has ideas about how to it better i would love to hear them!
Thanks,
Yoram

Associating CakePHP HABTM models without a view

I'm writing an import from CSV and have been able to successfully manually set data fields on a model in code by using the $this->Book->set() function and passing it a hash containing all of the fieldName => value pairings.
How do I create habtm associations in code? All the examples I've seen in the documentation are based on the $this->data returned from a form in the view. Because my data is coming from a csv file and not a view I can't use this!
So in the following example:
// Book habtm Tags
// Tag habtm Books
$this->Book->create();
$this->Book->set(
array(
'author' => 'tolkein',
'title' => 'lord of the rings')
);
$arrayOfTagIds = array(1, 5, 6);
// Do something with $arrayOfTagIds...
$this->Book->save();
How would I associate the $arrayOfTagIds with the Book?
Instead of using set to add data to the new entity and save to save it, use create and saveAll. In the example below, replace the BookTag model with the name of the model used in the relationship between books and tags. You'll also need to change tag_id to match the name of the field that represents the tag's id.
Example:
$book = array(
'Book' => array(
'author' => 'tolkein',
'title' => 'lord of the rings'
),
'Tag' => array(
'Tag' => array(1,5,6);
)
);
$this->Book->create($book);
$this->Book->saveAll();

Categories