JS helper stops working after I added prefix to action - php

I have controller with an add action.
public function add() {
$this->layout = 'manage';
$this->set($this->Restaurant->fetchRelatedData());
if ($this->request->is('post')) {
$this->Restaurant->create();
if ($this->Restaurant->save($this->request->data)) {
$this->Session->setFlash('ok!');
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash('Error!');
}
}
}
View for this action created with Form and Js helpers:
echo $this->Form->create('Restaurant');
// some fields
echo $this->Form->input('district_id', array('label' => 'District'));
echo $this->Form->input('street_id', array('label' => 'Street'));
// other fields
echo $this->Form->end(array('label' => 'Add'));
$this->Js->get('#RestaurantDistrictId')->event('change',
$this->Js->request(array(
'controller'=>'streets',
'action'=>'getByDistrict'
), array(
'update'=>'#RestaurantStreetId',
'async' => true,
'method' => 'post',
'dataExpression'=>true,
'data'=> $this->Js->serializeForm(array(
'isForm' => true,
'inline' => true
))
))
);
Js helper shows list with streets that are in choosen district.
StreetsController -> getByDistrict action:
public function getByDistrict(){
$district_id = $this->request->data['Restaurant']['district_id'];
$streets = $this->Street->find('list', array(
'conditions' => array('Street.district_id' => $district_id),
'fields' => array('street'),
'order' => array('Street'),
'recursive' => -1,
));
$this->set('streets', $streets);
$this->layout = 'ajax';
}
Everything worked fine until I added the administrative prefix to this action.
If action is named public function add() – all things works.
If action is named *public function admin_add()* – Js helper stops updating streets list on district change.

I'm not 100% sure on this, but I believe that the JS helper is preserving the admin prefix when it makes the AJAX request. When in add() it would call getByDistrict(). When in admin_add() it would call admin_getByDistrict(). Try passing 'admin' => false into Js->request.

Related

url parameter becomes null after clicking button

Here is my route:
'router' => array(
'routes' => array(
'upload' => array(
'type' => 'segment',
'options' => array(
'route' => '/products/upload[/:products]',
'defaults' => array(
'controller' => 'Products\Controller\Upload',
'action' => 'index'
),
),
'may_terminate' => true,
'child_routes' => array(
'uploadsuccessful' => array(
'type' => 'literal',
'options' => array(
'route' => '/uploadsuccessful',
'defaults' => array(
'controller' => 'Products\Controller\Upload',
'action' => 'successful'
),
),
),
),
),
),
);
I am trying to call this route several times from different view scripts giving different [/:products] parameter.
Upload Shoes Product Image
Upload Trainers Product Image
Upload Hat Product Image
Here is my Controller code.
<?php
namespace Products\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Products\Form\UploadForm;
class UploadController extends AbstractActionController
{
protected $_dir = null;
public function indexAction()
{
$products = $this->params()->fromRoute('products');
$config = $this->getServiceLocator()->get('Config');
$fileManagerDir =$config['file_manager']['dir'];
$this->_dir = realpath($fileManagerDir) .
DIRECTORY_SEPARATOR .
$products;
if (!is_dir($this->_dir)) {
//read, write, execute
mkdir($this->_dir, 0777);
}
$form = new UploadForm($this->_dir, 'upload-form');
$request = $this->getRequest();
if ($request->isPost()) {
$post = array_merge_recursive(
$request->getPost()->toArray(),
$request->getFiles()->toArray()
);
$form->setData($post);
if ($form->isValid()) {
$data = $form->getData();
$this->setFileNames($data);
return $this->redirect()->toRoute('upload/uploadsuccessful', array('products' =>$products));
}
}
return new ViewModel(array('form' => $form));
}
public function successfulAction()
{
$file = array();
$flashMessenger = $this->flashMessenger();
if ($flashMessenger->hasMessages()) {
foreach($flashMessenger->getMessages() as $key => $value) {
$file = $value;
}
}
return new ViewModel(array('file' => $file));
}
protected function setFileNames($data)
{
unset($data['submit']);
foreach ($data['image-file'] as $key => $file) {
rename($file['tmp_name'], $this->_dir . DIRECTORY_SEPARATOR . $file['name']);
}
}
}
I think the idea is clear: for each [/:products] parameter I tried to make separate folder with given name in $fileManagerDir.
But, there is a problem. When I click on button upload ($request->isPost() == true) parameter $products becomes null and uploaded files don't go to appropriate folders. Also I am not able to redirect to successful action - the error appears "missing parameter" because $products is null.
In your view script the upload buttons are href links. This will result in a GET REQUEST being sent to the controller and not a POST and no FILES will be present either. Unless that is, you are intercepting the click event with external JS which you haven't mentioned here. The route url's should be in the form action attribute. The submit buttons should be buttons not links (unless you are using JS not mentioned here). Make sure the form method is set to POST.
Something like:
<form action="<?php echo $this->url('upload', array('products' =>'shoes')); ?>" method="post" enctype="multipart/form-data">
You'll need to deal with the dynamic action using JS or redesign your routing.

Magento custom admin module wysiwyg integration

I've created an admin module based off of the tutorial here. I'm attempting to change two of my form inputs to wysiwyg editors based off of information found here. However, whenever I load the edit page I get an error Call to a member function setCanLoadTinyMce() on a non-object. $this->getLayout()->getBlock('head') var_dumps to false.
Namespace/Slides/Block/Adminhtml/Slide/Edit.php looks as follows
class Namespace_Slides_Block_Adminhtml_Slide_Edit
extends Mage_Adminhtml_Block_Widget_Form_Container
{
protected function _prepareLayout()
{
parent::_prepareLayout();
if (Mage::getSingleton('cms/wysiwyg_config')->isEnabled()) {
$this->getLayout()->getBlock('head')->setCanLoadTinyMce(true);
}
}
protected function _construct()
{
//... Construction stuff
}
}
Namespace/Slides/Block/Adminhtml/Slide/Edit/Form.php
class Cfw_Slides_Block_Adminhtml_Slide_Edit_Form
extends Mage_Adminhtml_Block_Widget_Form
{
protected function _prepareForm()
{
//...Do some things first, like create the fieldset..
//Add the editable fields
$this->_addFieldsToFieldset($fieldset, array(
'foreground_image' => array(
'label' => $this->__('Foreground Image'),
'input' => 'image',
'required' => false,
),
'background_image' => array(
'label' => $this->__('Background Image'),
'input' => 'editor',
'required' => true,
'config' => Mage::getSingleton('cms/wysiwyg_config')->getConfig(),
'wysiwyg' => true,
),
'description' => array(
'label' => $this->__('Text Overlay'),
'input' => 'editor',
'required' => false,
'config' => Mage::getSingleton('cms/wysiwyg_config')->getConfig(),
'wysiwyg' => true,
)
));
return $this;
}
protected function _addFieldsToFieldset(
Varien_Data_Form_ElementFieldset $fieldset, $fields)
{
$requestData = new Varien_Object($this->getRequest()->getPost('slideData'));
foreach ($fields as $name => $_data) {
if ($requestValue = $requestData->getData($name)) {
$_data['value'] = $requestValue;
}
//Wrap all fields with slideData group
$_data['name'] = "slideData[$name]";
//Generally, label and title are always the same
$_data['title'] = $_data['label'];
//If no new value exists, use the existing slide data.
if (!array_key_exists('value', $_data)) {
$_data['value'] = $this->_getSlide()->getData($name);
}
//Finally, call vanilla funcctionality to add field.
$fieldset->addField($name, $_data['input'], $_data);
}
return $this;
}
}
I'm not sure if you need it, but here's my file structure as well
Namespace
-Slides
--Block
---Adminhtml
----Slide
-----Edit
------Form.php
-----Edit.php
-----Grid.php
----Slide.php
--controllers
---Adminhtml
----SlideConroller.php
--etc
---config.xml
--Helper
---Data.php
--Model
---Resource
----Slide
-----Collection.php
----Slide.php
---Slide.php
--sql
---namespace_slides_setup
----install-0.0.1.php
The issue is that Magento cannot find your head block.
Instead of using:
$this->getLayout()->getBlock('head')->setCanLoadTinyMce(true);
Try calling it like this:
Mage::app()->getLayout()->getBlock('head')->setCanLoadTinyMce(true);
If that doesn't work, it's a different issue but the problem is still that Magento can't find the head block.
I imagine you no longer need a solution for this, but I ran into the same issue using the same tutorial that you did.
The 'head' block (and thus setCanLoadTinyMce()) was unavailable in the Edit.php and the Form.php via the _prepareLayout() function.
The 'head' block was available in the controller(SlideController.php in your case) between $this->loadLayout() and $this->renderLayout within the editAction() function.
In SlideController.php change
$this->loadLayout()
->_addContent($brandBlock)
->renderLayout();
to
$this->loadLayout() ;
$this->_addContent($brandBlock);
$this->getLayout()->getBlock('head')->setCanLoadTinyMce(true);
$this->renderLayout();

ZfcUser and custom showAction()

I've got a problem. I'm using zfcuser in my project, and now i want to create profile pages. I'have created the showAction() in UserController, but when i put the url to webbrowser, i will got 404.
public function showAction()
{
$id = (int) $this->params()->fromRoute('id', 0);
if (!$id) {
return $this->redirect()->toRoute('zfcuser', array(
'action' => 'register'
));
}
try {
$user = $this->zfcUserAuthentication()->getIdentity()->getUser($id);
}
catch (\Exception $ex) {
return $this->redirect()->toRoute('zfcuser', array(
'action' => 'register'
));
}
return new ViewModel(array(
'user' => $user));
}
I also created custom function to get User info all in one row.
It looks like this:
public function getUser($id){
$rowset = $this->tableGateway->select(array('user_id' => $id));
$row = $rowset->current();
return $row;
}
And it is in Entity/User.php
This is my showAction() in zfc UserController.php
I thought its wrong module.config, but its not working anyway. I changed my module.config to this:
'show' => array(
'type' => 'Literal',
'options' => array(
'route' => '/show[/][:id]',
'defaults' => array(
'controller' => 'zfcuser',
'action' => 'show',
),
),
),
My problem is, i can not even get to url to show this controller action.
Where can be problem. I want to make simple user profile page.
The problem is in my opinion your route 'Literal'. A literal route can't have params.
You have to use Segment instead
But it's not the only problem i think.
ZfcUser comes with a packaging, profile page already exist :
Take a look to this complete slideshare :
Zf2 Zfc-User

cakephp insert data on database of linked models

I have two models "Ficha" and "Perigo":
class Ficha extends AppModel {
var $primaryKey = 'id_ficha';
public $validate = array(
'nome_produto' => array(
'rule' => 'notEmpty'
),
'versao' => array(
'rule' => 'notEmpty'
),
'data_ficha' => array(
'rule' => 'notEmpty'
)
);
}
class Perigo extends AppModel {
var $belongsTo = array(
'Ficha' => array(
'className' => 'Ficha',
'foreignKey' => 'id_fichas'
)
);
}
As you can see they are "linked". Now, in the code i have a form for Ficha that the method "add()" of FichasController redirects to my Perigo Model:
add() (of FichaController)
public function add() {
//pr($this->request->data); // to get the data from the form
if ($this->request->is('post')) {
$this->Ficha->create();
if ($this->Ficha->save($this->request->data)) {
$this->Session->setFlash('Your post has been saved.');
//$last_id=$this->Ficha->getLastInsertID();
//$this->redirect(array('action' => 'preencher_ficha'),$last_id);
$this->redirect(array('controller'=>'perigos', 'action' => 'add'),$last_id);
} else {
$this->Session->setFlash('Unable to add your post.');
}
}
}
The redirection is made to a form that exists in PerigosController.
add.ctp (of Perigo)
echo $this->Form->create('Perigo');
echo $this->Form->input('class_subst', array('label' => 'Classificação da substância ou mistura:'));
echo $this->Form->input('simbolos_perigo', array('label' => 'Símbolos de Perigo:'));
echo $this->Form->input('frases_r', array('label' => 'Frases R:'));
echo $this->Form->end('Avançar');
add() (of PerigoController)
public function add() {
if ($this->request->is('post')) {
$this->Perigo->create();
if ($this->Perigo->save($this->request->data)) {
$this->Session->setFlash('Your post has been saved.');
$this->redirect(array('controller'=>'perigos', 'action' => 'index'));
} else {
$this->Session->setFlash('Unable to add your post.');
}
}
}
but there's something i don't know how to do it. Since the models are relational, and the same happens with the two tables on the database (the table perigos has a foreignkey that is the primary key of the table "fichas", how can i insert the data on table perigos in database? I mean, how can i get the key of the Ficha inserted in the first form and insert her in the foreign key of "perigos" when i submit this second form?
As #mark says, your redirection is bad, it should include the id in the URL array:
$this->redirect(array('controller'=>'perigos', 'action' => 'add', $last_id));
Like this you are passing the parameter by URL.
In the add action of your PerigosController you should have an $idFicha param at the method:
//PerigosController.php
public function add($idFicha){
//here you can use $idFicha
...
//when submiting the Perigos form, we add the foreign key.
if($this->request->is('post')){
//adding the foreign key to the Perigo's array to add in the DB.
$this->request->data['Perigo']['ficha_id'] = $idFicha;
if ($this->Ticket->save($this->request->data)) {
//...
}
}
}
Data submitted by POST method in a form will be always contained in an array of this type: $this->request->data['Model_name']. In your case:
$this->request->data['Perigo']
Another way to do this, is using sessions if you prefer to hide the id value:
http://book.cakephp.org/2.0/en/core-libraries/components/sessions.html#sessions

Magento: Admin form action not correct

I want to add a new form to the edit customer page, so far so good, using rewrites to customer_edit_tabs i was able to add a tab and my admin form to the page. Code looks like this.
protected function _beforeToHtml()
{
$this->addTab('extraoptions', array(
'label' => Mage::helper('customer')->__('Extra options'),
'class' => 'ajax',
'url' => $this->getUrl('module/adminhtml_tabs/info', array('_current' => true)),
));
This adds my tab corrently. From there the link on the tabs controller:
public function infoAction()
{
$this->_init();
$this->getResponse()->setBody(
$this->getLayout()->createBlock('module/adminhtml_tabs_edit')->toHtml()
);;
}
This links to my form container on Block/Adminhtml/Tabs/Edit.php
class Namespace_Module_Block_Adminhtml_Tabs_Edit extends Mage_Adminhtml_Block_Widget_Form_Container{public function __construct()
{
parent::__construct();
$this->_objectId = 'id';
$this->_mode = 'edit';
$this->_blockGroup = 'module';
$this->_controller = 'adminhtml_tabs';
$this->_updateButton('save', 'label', Mage::helper('module')->__('Save'));
}
public function getHeaderText()
{
return Mage::helper('module')->__('Extra Options');
}
}
My Block/Adminhtml/Tabs/Edit/Form.php
class Namespace_Module_Block_Adminhtml_Tabs_Edit_Form extends Mage_Adminhtml_Block_Widget_Form
{
public function __construct()
{
parent::__construct();
}
protected function _prepareForm()
{
$form = new Varien_Data_Form(array(
'id' => 'info_form',
'action' => $this->getUrl('module/adminhtml_tabs/save', array('id' => $this->getRequest()->getParam('id'))),
'method' => 'post',
'enctype' => 'multipart/form-data'
)
);
$fieldset = $form->addFieldset('extra_options', array('legend' => Mage::helper('module')->__('Extra Options Fieldset')));
$fieldset2->addField('extra', 'text', array(
'name' => 'zip',
'title' => Mage::helper('module')->__('extra'),
'label' => Mage::helper('module')->__('extra data'),
'maxlength' => '250',
'required' => false,
));
$form->setUseContainer(true);
}
protected function _prepareLayout()
{
return parent::_prepareLayout();
}
Everything is fine, I have a new button below the default save customer buttons, but this save button does not update the action, so if i click it, it goes to the default customer/edit/save action, it does not tell me the method does not exist which it should. My guess is that there is something wrong with the container but i have tried three tutorials with little differences to no avail, hope someone can help and even maybe someone will find my code helpful.
In this line of code:
'action' => $this->getUrl('module/adminhtml_tabs/save')
You are telling Magento to look for a module named module, a controller aliased adminhtml_tabs, and a saveAction() method within that file.
You need to figure out where you want to send the user when a save needs to be performed, and then place it there (e.g. the route to your controller->saveAction() method).
I decided to create a new button to save with a custom action. On the container:
$this->_addButton('save', array(
'label' => Mage::helper('adminhtml')->__('Save Extras'),
'onclick' => 'document.myform.submit();',
'class' => 'save',
),-1,5);
This did the trick.

Categories