How do I get field data in Magento from a custom module? - php

I'm very new to Magento development (this is my first module). The purpose of this module is to fix some problems that we are having with the original one, while not making any changes to the model/controller. I am modifying this existing template, but I cannot seem to find a way to retrieve fields. The template is using:
$this->getChildHtml('submit_button');
to submit the data. This is ultimately making a call to a javascript/ajax function that pretty much leaves me at a dead end. I'm simply wanting to get the values of, let's say:
<textarea name="thing[other]" .../>
How would I retrieve that value so that my Model may manipulate it? Overriding the controller is not an option, this page is essentially a duplicate of another that uses the same controllers. The functionality of that controller is desired for that one, just not desired for this one.
or
My other option is to override the template. My problem with that is that the original module is using an observer to override the template, and I'm not sure how to override that.

You need to create a controller and set the form action to post to this controller. You can then access the post data by calling :
$postData = $this->getRequest()->getPost();

Related

Modify how Drupal builds fields on a per form basis

I want to change the way Drupal builds specific fields on a specific node edit/add form on my site. For example, when I use print drupal_render($form['textarea']); in my node--CONTENTTYPE--form.tpl.php file, I get the default Drupal render of the field widget. I want to modify the HTML markup of the field widget.
There are three ways I can think of that might solve this problem:
Using a forms equivalent of the theme_field() hook. This seems ideal, but after searching for the last few hours, I haven't found anything on this.
Building custom field widgets for every field type I'm using on that node. This is definitely not ideal and I have to believe there's an easy way to do this in Drupal from a theme point of view.
Manually build the HTML markup for the form and field in node--CONTENTTYPE--form.tpl.php with print $form['textarea']['und'][0]['title']; and the like.
Is there a hook in Drupal to do this, or must the code for every field I want to modify be manually generated?
I think the hooks you are looking for are hook_form_alter and hook_form_BASE_FORM_ID_alter. Refer to the Form API to know what you can set on the render array.

yii widget render partial view of another controller

I need to create universal dialog widget for different modules in my yii-powered project, with form which will be auto serialized and passed to controller action for add/update operations.
Is it a good practice if I call render partial method in overloaded run() or init() method of my widget and pass him custom view path with html form (this form will be shown in modal dialog window after dialog-btn click action accordingly)?
My widget path:
/protected/components/widgets/DialogFormWidget.php
My forms path:
/protected/modules/module/controller/views/forms/submittable_html_form.php
go with
$this->renderPartial('application.modules.controllers.views.forms.submittable_html_form');
UPDATE :
in above code, $this refers to the controller, if you want to use controllers renderPartial from inside a widget, you have to access it like $this->controller->renderPartial (
Even you can use path to your view file to access it from other controller ($this->renderPartial('application.views.controller.view', []) , or path to any place where your view live on system), this is not good solution. Better solution is to create Yii widget so u can easy call it from all places because its controller independent. You will have also lot of benefits since with Yii widgets u have option to send some widget configuration parameters that can be used to customize widget and even load different views/style based on that parameters. Also you will have good place for custom functions that can help to add some business logic to your view and similar.
You can find some start point for this here (http://www.yiiframework.com/doc/guide/1.1/en/basics.view)

Need a light understanding MVC pattern

You have the URL:
http:///www.site.com/controller/method/values/1/2/3
Do I have to always have the controller being called or can I have the view being called and instantiate the controller inside the view or in a bootstrap file referring to this view?
What I don't get it is if I need more than 1 controller on the view, how to archive that?
For example:
On my index page I want run a simple CMS, where the admin can change the text blocks and images of the site. That would be on the content management controller.
On my index page I also got the latest added products vitrine, what would be controlled by the controller products.
If I define www.site.com/contentmanagement or www.site.com to run the contentmanagement controller, how the product controller would be called?
Also, another example. On my menu I got a link to a page called aboutus, that would be a simple page and the only feature needed would be the content management controller to manage the texts blocks.
If I follow the pattern Im reading all over the place I will end with a link like:
http://www.site.com/contentmanagement/method/aboutus
?
Kinda lost here cause surely this URL will look weird. Would be much easier to have the URL calling the view http://www.site.com/aboutus and a boot file where I can tell the controller that should be loaded when the surfer is there ...
bootstrap would look like:
switch($view)
case: index
controller load contentmanagement
controller load product
case: aboutus
controller load contentmanagement
I appreciate any help or a light here, thanks.
by the way, Im coding in PHP.
Hm, if you want to have text blocks and images of the site (one controller), and products vitrine (second controller), then call the methods you need in one controller..
I would do it this way: when you request index page with all the elements you mentioned above, actually one controller is called, and it decides which view to show.. so in that controller, you call the all methods that you need, get the data, and pass it to the view.. if the methods are called from other controllers, just call that methods and get the data.. i often make some static methods in controllers, which I can call anywhere, so I don't have to instantiate whole object..
E.g. you call www.site.com/contentmanagement, controller is called, which will display index view, and in that controller, you call all methods you need, prepare the data, and pass that data to the final view which will be displayed..
Do I have to always have the controller being called or can I have (..blah blah..)?
It kinda depends on what you understand by "call".
Controller needs an ability to change state of both View and Model(s).
And each View need ability to request data (in Model2 MVC) from Model(s).
Thought Controller should not cause the rendering of View (which is common in all the RoR sycophants) much like View has not business in executing actions on the Controller.
What I don't get it is if I need more than 1 controller on the view, how to archive that?
Views and Controllers should have 1:1 relationship. If your view need more then one controller, you might want to look into HMVC architecture.
For example: On my index page I want run a simple CMS, (.. more blah .. ) how the product controller would be called?
CMS should be a separate application ( or at least module ) with multiple controllers.
If I follow the pattern Im reading all over the place I will end with a link like: http://www.site.com/contentmanagement/method/aboutus ?
Why not just http://site.com/cms/content/2/edit (where 2 is the ID for "about us" page). There is no law which states that URL structure for site administration must mirror the publicly available page .. hell .. it can actually cause increased vulnerability.
I am going to try to walk
What I don't get it is if I need more than 1 controller on the view,
how to archive that?
For example: On my index page I want run a simple CMS, where the admin
can change the text blocks and images of the site. That would be on
the content management controller. On my index page I also got the
latest added products vitrine, what would be controlled by the
controller products. If I define www.site.com/contentmanagement or
www.site.com to run the contentmanagement controller, how the product
controller would be called?
Having the URL to contains the controller's name is definitely nice, but it is not the requirement for MVC. So you don't have to necessary map your controller to the URL itself. A classic MVC does not tie itself to a particular naming convention, so you could call your product controller via different URL which then process the product and show the view for the product.The important for MVC is to have one controller that deals with sets of model and resulting in one view as the presentation layer. In your particular example, your entry point seems to be a single controller that interacts with both ContentManagement and Product Class/Module and the resulting interaction produce a single view.
bootstrap would look like:
switch($view)
case: index
controller load contentmanagement
controller load product
case: aboutus
controller load contentmanagement
Thus your original interaction above is not completely off, except that you are not really calling two controllers, but rather doing the following upon hitting index:
Load a controller, let's call this one IndexController
Load ContentManagement module to get the related content, you might want to put the info as part of your Model for the Index page
Load Product module to get related products, again put this into your Model
Pass the Model containing the info for rendering the page into the View
In your View, you render the Model that contains both Content from ContentManagement module and Product list from the Product module thereby producing a single view
If I follow the pattern Im reading all over the place I will end with
a link like: http://www.site.com/contentmanagement/method/aboutus ?
This is again not a requirement, you should follow what makes sense and easier for the users. Also, if you are required to follow the conventions, you could always make your URL pretty by using URL mapping.
What you are looking for is called HMVC and there are a couple of frameworks for that out there, like Kohana.
Also see this question:
What is the HMVC pattern?

Dynamic Navigation Menu in CakePhp

I am working on a website where I have to use dynamic navigation menu on the sidebar.
I have set variables in the beforeFilter() method in AppController and using those variables, created an element for the sidebar.
I have 3 layouts and have used the element in all the 3 layouts.
I am not satisfied with this implementation as for every request the beforeFilter() method in the AppController has to be called.
Also it is not in accordance with the MVC pattern.
Is there any better way to achieve this?
Usually, I would choose to let a Category model handle the retrieval of (sub)categories. You could then call the appropriate action from beforeRender (to prevent loading data while you never reach a point to render it) and, if necessary, pass the appropriate environmental values to your model.
On a sidenote, I usually apply the TreeBehaviour to the Category model. You've probably already done this but I couldn't make that up from your question.
Sincerely,

How should I go about capturing a custom form in Magento that is stored with the order?

I am working on a module to add a new step called Rental into the Onepage Checkout module in magento. The problem is not adding a step it is the data capture.
I want to be able to take the custom form I have created and store it with the rest of the order information so when I click view order in the backend, it shows the information in the form as a seperate box.
Preferably I want to seperate the concerns by creating a standalone module.
How would you go about doing this? What would be your personal strategy for implementing this?
Firstly, it should all depend on what data 'Rental' would be. Could it fit/be appropriately placed inside a product's custom option? Or do you need to create a custom sales attribute to store the data in?
If you want the latter, you should use Magento Module Creator by SilkSoftware to create a module to implement sales attributes.
Also: a good thread / scenario in using sales attributes: Magento: Setting a custom attribute on the sales/order_shipment model
Secondly, is capturing the form data -- this is assuming you already have a block/form created and showing on the checkout page. I highly encourage you name the fields in the following semantic:
<input type="text" name="rental[text_data]" />
<input type="text" name="rental[text_data2]" />
Where text_data and text_data2 are your desired variable names.
An order is submitted / saved finally via a Controller action called saveOrderAction in Mage_Checkout_OnepageController or whatever Controller class you are using currently for your checkout page. Don't edit the corresponding PHP Class file for this found at app/code/core/Mage/Checkout/controllers/OnepageController.php ! Since you want to separate this into another module, you should try and rewrite this controller then so that your custom Controller class inside your module that extends the aforementioned base class (Mage_Checkout_OnepageController) should be used by Magento in its stead.
A good tutorial on rewriting controllers can be found here.
You can then do either of the two options from here:
1.) you could copy the entire saveOrderAction function and create routines to save Rental data there. if you followed the naming semantic I suggested, you should be able to retrieve the form data doing so:
<?php
// app/code/local/Namespace/Module/controllers/Checkout.php
class Namespace_Module_Checkout extends Mage_Checkout_OnepageController {
public function saveOrderAction() {
.....
$this->getOnepage()->getQuote()->save();
$rental = $this->getRequest->getParam('rental');
$text_data = $rental['text_data'];
$text_data = $rental['text_data2'];
someSaveRoutine($text_data, $text_data2);
//..or someSaveRoutine($rental);
.....
}
}
2.) secondly, you could replace the above code with a custom event dispatch
$rental = $this->getRequest->getParam('rental');
Mage::dispatchEvent('checkout_onepage_controller_saveorder', array('rental'=> $rental));
then make an appropriate observer to save your custom data somewhere.
I know this isn't much, but it's a start. I will look into editing this to elaborate more in the near future.

Categories