plugin override Joomla MVC not working - plugins

Hellow !
I must use Joomla for a website and I need to override an MVC component (com_contact) to add a field to the contact form. The problem is, I followed this tutorial :
https://docs.joomla.org/How_to_override_the_component_mvc_from_the_Joomla!_core/fr
I installed the plugin, rewrote needed files and place them where the tutorial says to place them, but it doesn't work, the plugin is not overidden.
Could someone help me with this please ?
------EDIT---------
I gave up the first tutorial and am now trying to follow this one :
https://docs.joomla.org/J3.x:Creating_a_Plugin_for_Joomla/fr
but my plugin dosen't work. Here is the code of the plugin:
/**
* Prepare form and add my field.
*
* #param JForm $form The form to be altered.
* #param mixed $data The associated data for the form.
*
* #return boolean
*
* #since <your version>
*/
function onContentPrepareForm($form, $data)
{
$app = JFactory::getApplication();
$option = $app->input->get('option');
switch ($option) {
case 'com_contact': {
if ($app->isAdmin()) {
JForm::addFormPath(__DIR__ . '/forms');
$form->loadFile('item', false);
}
return true;
}
}
return true;
}
}
?>
the contact.xml
<?xml version="1.0" encoding="UTF-8"?>
<form>
<fields name="params">
<fieldset name="params" label="PLG_CONTENT_EXAMPLE_FIELDSET_LABEL">
<field
name="contact_emaillabel2"
type="text"
label="PLG_CONTENT_EXAMPLE_CONTACT_EMAILLABEL2"
/>
<field
name="contact_email2"
type="text"
label="PLG_CONTENT_EXAMPLE_CONTACT_EMAIL2"
filter="email"
/>
</fieldset>
</fields>
</form>
install xml file :
<?xml version="1.0" encoding="utf-8"?>
<extension version="3.2" type="plugin" group="override">
<name>test</name>
<author>Laurine</author>
<creationDate>June 2016</creationDate>
<copyright>Copyright (C) Page Graphique, tous droits réservés</copyright>
<authorEmail>Laurine#page-graphique.fr</authorEmail>
<version>3.2</version>
<description>Plugin pour surcharger les composants MVC</description>
<files>
<filename>plgoverridetest.php</filename>
</files>
<config>
</config>
</extension>
arborescence :
- <Joomla>/.../plugins/override
plgoverridetest.php
install.xml
- forms
contact.xml

You can check this link. It will definitely help you https://docs.joomla.org/Adding_custom_fields_to_core_components_using_a_plugin.
For site usage you can use
case 'com_contact':
if ($app->isSite())
{
JForm::addFormPath(__DIR__ . '/forms');
$form->loadFile('contact', false);
}
return true;
Then you need to edit the template file. Details you can get from that link.

In order to override the contact form, you need to create a 'content' plugin, your plugin above is 'override' so it will not be fired by the contact component.
Also, in your code $form->loadFile('item', false); is wrong because the xml file you're trying to load is 'contact.xml' so your code should be $form->loadFile('contact', false);.
I've just completed the development of a plugin that adds many fields such as phone, website, company, file upload, newsletter and includes switching off the default fields if need be. It also sends the information to HubSpot if you use their CRM.
Now the thing is in order to use these extra fields you need to create a 'contact' plugin that's fired when the form is submitted and triggered with the plugin trigger 'onSubmitContact($data)', I've created a 'custom reply' plugin for this purpose.
You need to remember when using a custom reply plugin you must select the 'Custom Reply' option on the contact options in the admin component.
Also, the plugins I've created work on a per form basis rather than having the same fields on multiple forms you can modify each form independently.

Related

Tapestry 5 custom component in form - access during validation

A have problem with accessing my custom components (which are used as parts of the form).
Here is the story:
I have dynamic form which have few modes of work. Each mode can be selected and loaded into form body with AJAX. It looks like that (template):
<t:form t:id = "form">
<p class= "calcModeTitle">
${message:modeLabel}: <select t:id="modeSelect"
t:type="select"
t:model="modesModel"
t:value="selectedMode"
t:blankOption="NEVER"
t:encoder="modeEncoder"
t:zone = "modeZone"
/>
</p>
<div class="horizontal_tab">
<t:errors/>
</div>
<t:zone t:id="modeZone" id="modeZone" t:update="show">
<t:if test="showCompany">
<t:delegate to="block:companyBlock" />
</t:if>
<t:if test="showPersonal">
<t:delegate to="block:personalBlock" />
</t:if>
<t:if test="showMulti">
<t:delegate to="block:multiBlock" />
</t:if>
</t:zone>
<t:block id="companyBlock">
<t:modes.CompanyMode t:id="company"/>
</t:block>
<t:block id="personalBlock">
<t:modes.PersonalMode t:id="personal" />
</t:block>
<t:block id="multiBlock">
<t:modes.MultiMode t:id="multi" />
</t:block>
<div class="horizontal_tab">
<input type="submit" value="${message:submit_label}" class="submitButton thickBtn"/>
</div>
</t:form>
AJAX works pretty well and form changes accordingly the "modeSelect" state. But i run into problem when submitting the form. I have in class definition hooks for components placed as:
//----form elements
#Component(id = "form")
private Form form;
#InjectComponent
private CompanyMode company;
#InjectComponent
private PersonalMode personal;
#InjectComponent
private MultiMode multi;
where *Mode classes are my own components, containing form elements and input components. I planned to get access to them during validation, and check values supplied by user with form, but when I am trying to reach anything from them I've got nullPointerException - it seems that component are not initialized in my class definition of form. On the other hand form component is injected properly (I am able to write some error for example). I am a bit lost now. How to properly inject my components to class page containing the form?
Dynamic forms in tapestry are a bit complicated. Tapestry passes a t:formdata request parameter which contains the serialized form entities. This is then used serverside in the POST to re-hydrate initial form state. This must be kept up-to-date with what the client sees.
If you want to add dynamic content to a form via ajax, you will need to use the FormInjector. You might want to take a look at the source code for the AjaxFormLoop to see an example.
If you want to render hidden form fragments and make them visible based on clientside logic, you can use the FormFragment
From tapestry guide:
A block does not normally render; any component or contents you put
inside a block will not ordinarily be rendered. However, by injecting
the block you have precise control over when and if the content
renders.
Try to use here either "t:if" or "t:delegate".
Something like this:
<t:zone t:id="modeZone" id="modeZone" t:update="show">
<t:delegate to="myBlock" />
</t:zone>
<t:block t:id="companyBlock">
<t:modes.CompanyMode t:id="company"/>
</t:block>
<t:block t:id="personalBlock">
<t:modes.PersonalMode t:id="personal" />
</t:block>
<t:block t:id="multiBlock">
<t:modes.MultiMode t:id="multi" />
</t:block>
java:
#Inject
private Block companyBlock, personalBlock, multiBlock;
public Block getMyBlock(){
if (getShowCompany()) return companyBlock;
if (getShowPersonal()) return personalBlock;
return multiBlock;
}

How to bind form based actions like 'Save' to designated Java classes mentioned in xwork in Confluence

I have made some significant progress in my customization efforst thanks to your help and looking forward to move forward similarly.
I have created the custom tab in the 'Advanced' tab and it now looks like this.
I have been able to add a text field as well as a 'Save' button. I actually followed the 'Edit Space Details' option and took two of its form elements to achieve the output.
This is how my VM looks now.
##requireResource("confluence.web.resources:space-admin")
<html>
<head>
<title>Freeway Project Creation</title>
<meta name="decorator" content="atl.general" />
</head>
<content tag="key">$action.space.key</content>
<body>
#applyDecorator("root")
#decoratorParam("helper" $action.helper)
#decoratorParam("context" "space-administration")
#decoratorParam("mode" "view-space-administration")
#applyDecorator ("root")
#decoratorParam ("context" "spaceadminpanel")
#decoratorParam ("selection" "add-fpc-label-action-web-ui")
#decoratorParam ("title" $action.getText("action.name"))
#decoratorParam ("selectedTab" "admin")
#decoratorParam("helper" $action.helper)
<div >
<table width="95%" border=0 cellspacing=0 cellpadding=5>
<form name="editspace" method="POST" >
#bodytag( "TextField" "label='space-name'" "name='name'" "size=40" )
#param ("labelwidth" "100")
#param ("tdcolor" "f0f0f0")
#end
<tr>
<td colspan="2" align="center">
#tag( "Submit" "name='confirm'" "value='update.name'" "theme='notable'" )
#tag( "Submit" "name='cancel'" "value='cancel.name'" "theme='notable'" )
</td>
</tr>
</form>
</table>
</div>
#end
#end
</body>
</html>
I would like to understand how this interaction with my JAVA class will result in the output like. For eg: I will enter the name in the text box for name and hit save and on a resulting page it must display the name entered.
As of now my designated java class looks like this.
package com.atlassian.myorg;
import com.atlassian.confluence.core.ConfluenceActionSupport;
import com.atlassian.confluence.pages.AbstractPage;
import com.atlassian.confluence.pages.actions.PageAware;
import com.opensymphony.xwork.Action;
/**
* The simplest action possible
*/
public class FreewayProjectAction extends ConfluenceActionSupport
{
#Override
public String execute() throws Exception
{
return Action.SUCCESS;
}
}
So I have 3 questions:
The 'Edit Space Details' shows the following URL 'http://localhost:1990/confluence/spaces/doeditspace.action?key=LBTEST' when i mouse over the 'Save' button. I am assuming that its governing Java class is EditSpaceDetails. So is the doEdit() method (see here )inside that class that swings into action when we try to save the edit action of the space ? Can i get to see the xml that has this mapping specifically for this edit space details action? Is my assumptin correct ?
In order to have such a functionality i have mentioned earlier i.e. displaying the name entered in my custom page as detailed above what will be the changes required in my Java class.
In the page i have just customised there is the text box and the label is 'Name' . Should i use a different xml so that i can provide my custom label like "Project Name" ?
Please do kindly advice me on the same.
Thanks
Angie
to answer your first question - you're able to get a deeper insight into the xwork action mappings, interceptors and possible result types if you're taking a look at confluence-core/confluence/src/etc/java/xwork.xml.
The following example is the corresponding mapping for your "doeditspace.action":
<action name="doeditspace" class="com.atlassian.confluence.spaces.actions.EditSpaceAction" method="doEdit">
<param name="RequireSecurityToken">true</param>
<result name="error" type="velocity">/spaces/editspace.vm</result>
<result name="input" type="velocity">/spaces/editspace.vm</result>
<result name="cancel" type="redirect">viewspacedetails.action?key=${key}</result>
<result name="success" type="redirect">viewspacedetails.action?key=${key}</result>
</action>
So if the return value from your execute method is ActionType.SUCCESS or "success", the request will be redirected to the viewspacedetails action.
Additional information is documented in the Atlassian Developer Website:
https://developer.atlassian.com/display/CONFDEV/XWork-WebWork+Module

Sharepoint 2007 - Custom List provisioning - are List Forms needed at deployment?

I have a feature which is provisioning 1 document library and 2 custom lists. A folder is included for each list containing the schema.xml for that list. Each folder also contains the associated forms (AllItems, DispForm, EditForm, NewForm, etc.). Everything deploys/works correctly but it seems a little redundant having the same forms copied into each list's folder. There is nothing special about these lists - the are basically a default doc library/generic list with additional fields provided through new content types (derived from Item/Document).
As far as I can tell these forms are pretty generic. Are there pre-installed forms that I can reference from my list so I don't have to deploy all of these extra files? Is there any reason I would not want to do this?
Update - moving xml in comment to original question for readability:
<Forms>
<Form Type="DisplayForm" Url="Forms/DispForm.aspx" WebPartZoneID="Main"/>
<Form Type="EditForm" Url="Forms/EditForm.aspx" WebPartZoneID="Main"/>
<Form Type="NewForm" Url="Forms/Upload.aspx" WebPartZoneID="Main"/>
<Form Type="NewFormDialog" Path="EditDlg.htm">
....
There are virtual defaults that are used if you don't specify a concrete page.
All lists use these template defaults unless you use a tool like SharePoint designer to customize the page. Then the template is used to create the concrete page and you can customize the look for a particular list without affecting others.
For my custom definitions, I use
<List>
...
<MetaData>
...
<Forms>
<Form Type="DisplayForm" Url="DispForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
<Form Type="EditForm" Url="EditForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
<Form Type="NewForm" Url="NewForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
</Forms>
</MetaData>
</List>
If you have no reason to customize the out of the box version of these forms, you can use the virtual form and not deploy copies.

Zend_Form - XML

I set up my Zend_Form with XML, now just one line I couldn't transfer to XML.
/* Do some stuff like $form = new Zend_Form etc */
$form->removeDecorator('HtmlTag');
How could I add removeDecorator to XML?
My try:
<forms>
<login>
<action>form/</action>
<method>post</method>
<options>
<removeDecorator>HtmlTag</removeDecorator>
</options>
<elements>
<!--- stuff --->
</elements>
</login>
</forms>
But it don't remove the <dl class="zend_form">.
You can’t. Zend_Form will translate your configuration keys to calls for set*() methods. Use the configuration files to set and add properties, and code PHP to remove things.

Custom forms in Magento

Can anyone provide a dummy guide \ code snippets on how to create a front end form in Magento that posts data to a controller action.
Im trying to write a variant of the contact us from. (I know its easy to modify the contact us form, as outlined here). I'm trying to also create a feedback form with additional fields.
Given this basic form:
<form action="<?php echo $this->getFormAction(); ?>" id="feedbackForm" method="post">
<div class="input-box">
<label for="name"><?php echo Mage::helper('contacts')->__('Name') ?> <span class="required">*</span></label><br />
<input name="name" id="name" title="<?php echo Mage::helper('contacts')->__('Name') ?>" value="<?php echo $this->htmlEscape($this->helper('contacts')->getUserName()) ?>" class="required-entry input-text" type="text" />
</div>
<div class="button-set">
<p class="required"><?php echo Mage::helper('contacts')->__('* Required Fields') ?></p>
<button class="form-button" type="submit"><span><?php echo Mage::helper('contacts')->__('Submit') ?></span></button>
</div>
</form>
What are the basic step I need to take to get inputted name to a controller action for processing?
If any one is interested, I solved this by building my own module which was heavily based on the Magento_Contacts module.
Here are some links that helped me figure things out.
http://www.magentocommerce.com/wiki/custom_module_with_custom_database_table
http://inchoo.net/ecommerce/magento/magento-custom-emails/
To make $this->getFormAction() return the URL to your custom controller, you have two options:
call setFormAction() somewhere else on the block.
use a custom block type that implements getFormAction().
(1) is what happens in Mage_Contacts_IndexController::indexAction(), but (2) is the cleaner approach and I'm going to explain it in detail:
Create a custom module
app/etc/modules/Stack_Form.xml:
<?xml version="1.0"?>
<config>
<modules>
<Stack_Form>
<active>true</active>
<codePool>local</codePool>
</Stack_Form>
</modules>
</config>
app/code/local/Stack/Form/etc/config.xml:
<?xml version="1.0"?>
<config>
<modules>
<Stack_Form>
<version>0.1.0</version>
</Stack_Form>
</modules>
<frontend>
<routers>
<stack_form>
<use>standard</use>
<args>
<module>Stack_Form</module>
<frontName>feedback</frontName>
</args>
</stack_form>
</routers>
</frontend>
<global>
<blocks>
<stack_form>
<class>Stack_Form_Block</class>
</stack_form>
</blocks>
</global>
</config>
This configuration registers the stack_form block alias for own blocks and the feedback front name for own controllers.
Create custom block
app/code/local/Stack/Form/Block/Form.php
class Stack_Form_Block_Form extends Mage_Core_Block_Template
{
public function getFormAction()
{
return $this->getUrl('stack_form/index/post`);
}
}
Here we implemented getFormAction() to generate the URL for our custom controller (the result will be BASE_URL/feedback/index/post).
Create custom controller
app/code/local/Stack/Form/controllers/IndexController.php
class Stack_Form_IndexController extends Mage_Contacts_IndexController
{
public function postAction()
{
// your custom post action
}
}
If the form should behave exactly like the contact form, just with a different email template and additional form fields, there are two solutions that I have outlined at https://magento.stackexchange.com/q/79602/243 where only one of them actually requires a custom controller action to send the form:
If you look at the contacts
controller
used in the form action, you will find that
the transactional template is taken directly from the configuration
all POST data is passed to the template (as template variable data), so that you can add any additional fields to the form
template and use them in the email template. But validation is hard
coded for "name", "comment", "email" and "hideit".
So, if you need a completely different email template or
additional/changed input validation, your best bet is to create a
custom controller with a modified copy of the postAction of
Mage_Contacts_IndexController.
But there is another solution that is a bit limited but without any
custom code involved:
create a hidden input that determines the type of the form. It could be just <input type="hidden" name="custom" value="1" />.
in the contact transactional email template, use the if directive to show different content based on the form type:
{{if data.custom}}
... custom contact form email ...
{{else}}
... standard contact form email ...
{{/if}}
How to use this custom block
You can add the form anywhere in the CMS using this code (CMS directive):
{{block type="stack_form/form" template="path/to/your/form.phtml"}}
If you do this, you need to add "stack_form/form" to the block whitelist under System > Permissions > Blocks!
Or in the layout using this code (layout XML):
<block type="stack_form/form" name="any_unique_name" template="path/to/your/form.phtml" />
Solution without custom module
If you use the solution without custom controller and a single email template mentioned above, you can set the form action using layout XML as well.
To achieve this, we use the feature to call helpers as parameters for block actions. Unfortunately, the core helper does not have a public method to get a URL but the helper from Mage_XmlConnect has, so you can use that one:
<block type="core/template" name="any_unique_name" template="path/to/your/form.phtml">
<action method="setFormAction">
<param helper="xmlconnect/getUrl">
<route>contacts/index/post</route>
</param>
</action
</block>
In the CMS directive you cannot use helpers, so there you would need to put the actual URL:
{{block type="stack_form/form" template="path/to/your/form.phtml" form_action="/feedback/index/post"}}
Since you probably have different CMS pages/blocks in different store views, this should not be a big problem.