How to create a reusable module in Zend Framework? - zend-framework

For various reasons, in my latest project I need to provide an almost identical view/feature both in the admin back end, as well as in the front end. What is the best way to do this?
Example of what i need:
There exists a table, with some crud controls. I need to show this table in the frontend without the controls, and in the backend with these controls. The main thing is, that they have to look alike, and when I make a visual change in one, the other should follow suit. Therefore it sounds logical, to have but one, and then reuse it, while passing on parameters to that determine whether the controls are shown.
But how do I do this in Zend Framework?

I'd just create a view partial for the table which relies on a parameter to show / hide controls.
<?php echo $this->partial('my-table.phtml', 'module-name', array(
'showControls' => true
)) ?>
Using the three argument version of the partial helper lets you keep the partial script in one particular module where you can reference it from anywhere else.

Related

SYMFONY FORM - filter attribute form on top with submit button, that provides a table with other form used to edit each row details

I am looking for best practices on SYMFONY FORM handling to achieve the following standard page (surprisingly I haven't found anything similar existing yet on SO).
Here is a shema of what I want to achieve:
As you can see at the top there is a SYMFONY FORM to filter the results that should be displayed.
It displays a table and each tuple of the table should permit to open another SYMFONY FORM kind linked to the tuple.
I am in the process of learning SYMFONY FORM, so far, I can manage to create the top row FORM to set the filter that'll apply to the table display.
But I wonder if anyone has experience on the second part: Displaying the table that embed as well many forms of a similar kind -That seems a bit more complex. I read about TWIG.EXTENSION and FORM.COLLECTION, I'll investigate that. But if someone could save me to re-invent the wheel and lead me to some direct shortcut, I'd be really grateful.
No idea if it's the best practice, but one way to do it would be to create a new property for your entity being listed in this table, called $editionForm (without mapping it to the database) for example.
Then, either throught a custom loop or by listening to a doctrine (or any ORM you use) hydration event (or triggering such an event if you don't use any ORM), fill the property with the generated form, probably within a dedicated service.
Then, just use it in your template like this :
$entity->getEditionForm()->render()

SugarCRM fetching data from outside REST service to subpanel

I'm trying to create subpanel in Account detail view where list of elements is fetched from external REST service.
I know how to define subpanel, but have no idea how to fill it with data from external network source. Was trying to use get_subpanel_data but there I can only change SQL.
Any ideas how can I do this?
When I've done this in the the past, at least with Sugar 6, I opted distinctly not to try to create a true subpanel. The data being loaded is coming from an outside source and is loaded dynamically with the page, so why present it as if it's static data coming from Sugar? Instead, I created a custom Smarty template to use as the footer on the detail page. For such an example, you can check how it works on the Calls Edit View. I think it's the footerTpl parameter in the detailviewdefs.php or editviewdefs.php. I loaded the smarty template by creating a custom detail view for my module, so custom/modules/MyModule/views/view.detail.php - extend the base Detail View class and override the display to feed Smarty new params, then your Smarty template only needs to iterate through and present the data that your view defined.
To be super-hip and abide by MVC, you could even put your custom code into your bean (if it's a custom module) or into a custom controller method, then reference that from the view.detail.php, and still feed it from there to the Smarty template.
Alternatively, you could just load JavaScript into the Smarty template and use the JavaScript to call the third-party service, parse and present it, etc.
I realize this question is a little bit old now however it comes up fairly often so why not provide an answer with a couple possible solutions. I won't get into code but more just into the design theory of how it can work. If someone needs more specific code help then that is another question.
A couple ideas...
As you mentioned you can define a custom Function which will load in Data to the SubPanel from your own SQL Query. That is one method that I just recently got to finally put to use after knowing about it for a good year and a half.
When you go this route, you are restrained to using the Columns in the SubPanel. I assume it is using the actual Metadata files to determine which Field Columns a SubPanel can use so you pretty much need your custom data in a Database table to have the same column names as the fields defined in the SubPanel Metadata.
Obviously this works great in the right situation, however not always and that leads us into the 2nd method I know of.
The other way is pretty much what #Mattew-Poer mentioned in his answer. It means abandoning the SubPanel altogether and instead generating your own HTML. This is by far my favorite and prefered way of doing it and I have been some really custom modules due to this being possible in a custom module! I will show an example below.
(Click HERE to View full size image)
In the screenshot, you can see in this example that I have something looking Similar to a SubPanel however it is not and is much for flexible and easy to customize.
Example, to the far left column in my fake subpanel is image checkboxes. When clicked on, an AJAX request is made to change the Task row Status.
After that, the checkbox image is updated to indicate the new Status state, the Modified DateTime is updated, the Status column has color background SPANS and is also updated with the correct text and background color when the left side checkbox is clicked.
Doing any of this with the standard SubPanels is a complete nightmare and would be difficult to do some of the stuff that you are open to do when you build your own version of a SubPanel.
With that said, I have built an identical clone of the above screenshot using SugarCRM default SubPanels! It was a nightmare. I could easily update the content and HTML in some of the columns. I even had the AJAX click checkbox image to update and do all the other updates I mentioned above. It wasn't too hard and worked fairly good but it had some issues.
When you do inline edit, inline create record, or subpanel paging to load different set of record. You would then lose all the custom HTML formatting that was applied. The reason is, in the SubPanel you are limited to using the After UI load logic hook. So since the "Page" is loaded already, when an AJAX request is made to add/edit the subpanel content or load a new set of items with the paging links. It only loads the SubPanel content on those events and the whole Page content does not reload. Because the logic hook only fires off 1 time after the page loads, this newly loaded subpanel data doe not receive any of your custom HTML formatting.
In my case, this means that nice looking colored background Status spans are lost, the image checkboxes are lost, and some other functionality is lost.
Now to get super technical, I could have gone another 3rd route and instead made new Custom Field Types for each SubPanel filed that I needed to apply custom HTML to. This process is super hard in my experience and in some cases it really isn't the BEST solution.
Because of the reason explained, this is why my new modules use the Custom HTML route to generate my own version of a custom subpanel or whatever Data is needed in my Module pages! So far it is working better than I imagined and has opened doors for me to build custom SugarCRM modules that I previously didn't even realize would be possible to build due to some of the issues I mentioned above. Now I bypass them altogether and open the door to do pretty much anything!
I've got some really cool stuff for SugarCRM in the works right now. If anyone has any questions feel free to ask in a new question or for me personally in a comment here.

why use zend form decorators instead of individually rendering?

I am almost at the end of my rope trying to style my Zend form using decorators. Previously to avoid these issues I would create a form script extending zend_form, add whatever validators, labels, etc I needed then retrieved the element from my view script using $form->getElement('my_form_element');
that way I could wrap whatever css tags I wanted around the element. I thought I should learn how to use the built in decorators, but I'm starting to feel like it's a waste of my time. My old way seems easier, is there some reason I am not seeing that makes using custom decorators better?
In general decorators are used to dynamically add functionality without having to touch the code's core functionality and for a better re-usage of code. In Zend_Form however, I think that the decorator system (as well as Zend_Form in general) is unintuitive and heavily over-engineered and so it does exactly the opposite of what it should do: Help the developer to create better and more intuitive code faster.
In my opinion the usage of Zend_Form_Decorator makes only sense in the case where you have some extended logic that you plan to reuse throughout your project on multiple and different types of elements.
Let me give you two examples:
You want to add a tooltip icon next to an arbitrary form element with a nice icon and a fancy JavaScript hover box.
An element should be validated directly upon entering data by posting an AJAX request and adding either a green check mark on success or a red cross icon on failure next to the element.
With the decorator you can now separate the logic of the added functionality from that of the underlying element and so you can use the same code to add the tooltip and/or the live validation feature to a textbox element as well as any other element simply by adding all the decorators you want to the element.
There is also a great article from Matthew Weier O'Phinney, the lead developer of Zend Framwork, that gives some background insight on the motivations for using decorators along with a lot of examples: Decorators with Zend_Form
Decorators can come in handy if you have a specific repeatable markup for your forms, for example if you want to use Bootstrap. Other than that, especially if you have a good html/css person, I would avoid them.

Why no Zend_Layout helper or codebehind? And best way to

I was just wondering why no code-behind or helpers were made to work with layouts? I have stuff I want to display in my layouts without having to set it up in a placeholder for every single controller.
I was also wanted to know what is the best way to persist a display-once "success-message" across many pages. For example, a user fills out a form and when it is submitted correctly they are redirected to another page. I want the user to see a success message on that other page. Is there some sort of provision in Zend Framework that makes this easier?
Well for the messages you can use the Flash Messenger helper
As far as setting up the place holders you could use a base controller and set these up in the init method overriding on descendents when necessary.

Zend Framework - Dynamically adding "code modules" or classes

I'm building a Zend-based Web app that will permit third-party extensions.
Essentially, this application's database will have a generic "content store." Extensions are added to render different pieces of content in different ways.
Think of a rich mail store: When the user asks for a "Calendar" item, I instantiate a Calendar class (or something) and ask it to render the item's content. The same database might contain "Mail" items, which are rendered by a different class (or whatever). So I'm basically defining a base class with the needed methods to handle content items, and then add-ins are written which inherit from that to deal with specific item types.
Each of these add-ins may need to access its own View files, since each of them will obviously have a different visual layout.
I can't foresee all the content renderers that might be used; new ones will be "installed" (in some fashion) so that my application knows "when I see content with a database type column of XYZ, I'll call the XYZ thing to render that."
Likely, what will happen is this: User will visit a URL for the application, thus triggering an action within a Controller. That Controller will use a Model method, telling it which specific content item was requested.
From there, either the Model or the Controller (which?) needs to call something (what?) that gets the item from the database (okay, the Model clearly does that) and renders it using some predetermined View. This would be PART of a larger page that might well include several rendered items (as in, a list of content items).
So two questions:
What's the best way to architect this in Zend Framework? I do want these add-ins to inherit from a base renderer class that I provide, because very simple renderers may simply need to call functionality from that base class, rather than having any of their own code (e.g., a "Note" and a "Memo" might well use the simplified rendering functionality from the base renderer class).
What's the best way to "register" these add-ins with my application? An .ini file, perhaps a database table? The goal is simplified installation steps for whoever is operating the application - e.g., editing an .ini file is often easier than manually querying a database, although I could also provide an admin back-end UI for new content renderers to be registered in.
I'd implement the Visitor Pattern for this.
Each third-party extension should implement an interface that you define, so that you know you can call a specific method, say render() on any object that is an instanceof that interface.
Each extension then implements its own rendering. Perhaps it utilizes a View partial in the Zend Framework architecture. Or else perhaps it uses some totally different code to render itself as a PDF or something (maybe each extension needs to be able to override content-type headers?).
As for how to register it, check out the Zend_Application framework for defining resource plugins.