Problems with a form in SocialEngine/Zend - php

I have created a module in SocialEngine(*which is built on Zend framework v1.9) that contains an admin form with a few options.
The problem I have with it is that it seems to no get the values of the fields from database after I refresh the page and it shows me the default values.
It shows the correct values immediately after I save(*but I am not sure if the page is refreshed after saving), but not after I refresh.
controller /application/modules/Mymodule/controllers/AdminSomesettingsController.php :
class Mymodule_AdminSomesettingsController extends Core_Controller_Action_Admin
{
public function indexAction()
{
$this->view->form = $form = new Mymodule_Form_Admin_Someform();
$settings = Engine_Api::_()->getApi('settings', 'core');
if(!$form->isValid($settings->mymodule))
{ return $form->populate($settings->mymodule); }
if( !$this->getRequest()->isPost() ) { return; }
if( !$form->isValid($this->getRequest()->getPost()) ) { return; }
$db = Engine_Api::_()->getDbTable('settings','core')->getAdapter();
$db->beginTransaction();
try {
$values = $form->getValues();
$settings->mymodule = $values;
$db->commit();
} catch( Exception $e ) {
$db->rollback();
throw $e;
}
$form->saveValues();
$form->addNotice('Your changes have been saved.');
}
}
form /application/modules/Mymodule/Form/Admin/Someform.php :
class Mymodule_Form_Admin_Someform extends Engine_Form
{
public function init()
{
$this
->setTitle('My Settings')
->setDescription('Settings');
$this->addElement('Radio', 'some_setting', array(
'label' => 'Some Setting',
'description' => '',
'multiOptions' => array(
0 => 'Option One',
1 => 'Option Two',
2 => 'Option Three',
),
'value' => 1,
'escape' => false,
));
// Add submit button
$this->addElement('Button', 'submit', array(
'label' => 'Save Changes',
'type' => 'submit',
'ignore' => true
));
}
public function saveValues()
{
}
}
I have checked with other plugins and it seems to me that $form->populate($settings->mymodule); repopulates the form after refresh, but it does not work for me.
Any idea how I could make it show the values from the database(*when these values exist) instead of the default values?

I myself am new to socialengine and zend.My understanding of socialengine says, make a function saveValues() inside ur form class, then call it from controller action as $form->saveValues(),passing parameter as needed.This is the convention that socialengine seems to follow, and inside the saveValues() of form class,u can save valus as needed.Ur form shud be populated only if validation fails
(!$form->isValid($formData ))
{ return $form->populate($formData); }
Instead of default adapter,U should try this-
$db =Engine_Api::_()->getDbTable('settings','core')->getAdapter(),
$db->beginTransaction();
If u want to set the value of a particular field try - $form->populate(array('formField'=>'urValue')); in ur case maybe -
$val=$settings->mymodule,
$form->populate('formField'=>$val);

You can add the code in controller $form->some_setting->setValue('1');

Related

Trying to remove/hide fields in custom tab in SilverStripe

I am trying to figure out a way (if possible) to remove or hide certain fields in a custom tab. The custom tab is labeled "Rotator" and it holds images that can be used for a rotating banner on a page. The home page banner is a little different in that it has 2 extra fields that aren't needed on the subpages: BackgroundImage and Body(which is meant to hold a variety of text). I want to make things simple for the content manager, so I want to hide these fields on the subpages.
I am aware of removeFieldFromTab and how it works, and I was thinking of using it on the Page.php file (since that is basically the main template for all page types in my SilverStripe file):
public function getCMSFields() {
$fields = parent::getCMSFields();
$gridFieldConfig = GridFieldConfig_RecordEditor::create();
$gridFieldConfig->addComponent(new GridFieldBulkImageUpload());
$gridFieldConfig->addComponent(new GridFieldSortableRows('SortOrder'));
$gridFieldConfig->getComponentByType('GridFieldDataColumns')->setDisplayFields(array(
// field from drawer class => label in UI
'ID' => 'ID',
'Title' => 'Title',
'Thumbnail' => 'Thumbnail',
'InternalURL.Link' => 'Internal URL',
));
$gridfield = new GridField(
"Rotator",
"Rotator",
$this->Rotator()->sort("SortOrder"),
$gridFieldConfig
);
$fields->addFieldToTab('Root.Rotator', $gridfield);
$fields->addFieldToTab("Root.Main", new TextField("H1"), "Content");
$fields->addFieldToTab("Root.Main", new TextField("Subheader"), "Content");
$fields->addFieldToTab('Root.Main', new TextField('PageTitle', 'Page Title'), 'MetaDescription');
$fields->removeFieldFromTab('Root.Rotator', 'Body');
$fields->removeFieldFromTab('Root.Rotator', 'BackgroundImage');
return $fields;
}
Here is the code for the Rotator class:
<?php
class RotatorImage extends DataObject {
public static $db = array(
'SortOrder' => 'Int',
'Header' => 'varchar',
'Body' => 'HTMLText',
);
// One-to-one relationship with gallery page
public static $has_one = array(
'Image' => 'Image',
'BackgroundImage' => 'Image',
'Page' => 'Page',
'InternalURL' => 'SiteTree',
);
// tidy up the CMS by not showing these fields
public function getCMSFields() {
$fields = parent::getCMSFields();
$fields->removeFieldFromTab("Root.Main","PageID");
$fields->removeFieldFromTab("Root.Main","SortOrder");
return $fields;
}
// Tell the datagrid what fields to show in the table
public static $summary_fields = array(
'ID' => 'ID',
'Title' => 'Title',
'Thumbnail' => 'Thumbnail',
'InternalURLID' => 'Internal URL',
);
// this function creates the thumnail for the summary fields to use
public function getThumbnail() {
return $this->Image()->CMSThumbnail();
}
public function canEdit() {
return true;
}
public function canDelete() {
return true;
}
public function canCreate(){
return true;
}
public function canPublish(){
return true;
}
public function canView(){
return true;
}
}
However this does not work, and I am sure that I have the fields names correct. I tried 'Root.Rotator.Main' and 'Root.Rotator.Content' just to see what would happen and those also did not work. What am I missing? Is it possible to hide fields on a custom tab this way, or do I need to try something else?
well, you want to hide the fields in the gridfield detail form? that cannot be done in your pages getCMSFields(), as the grid is responsible for generating the detail form. Two possible solutions:
1) tell the grid to hide that fields with a custom component. I dunno how to do it
2) tell your Rotator class to show the fields ONLY if the related page is a homepage:
public function getCMSFields() {
$fields = parent::getCMSFields();
//...other stuff....
$isOnHomePage = ($this->Page() && $this->Page()->ClassName == 'HomePage'); //put in your own classname or conditions
if(!$isOnHomePage) {
//remove the fields if you're not on the HomePage
$fields->removeByName('Body');
//we need to suffix with "ID" when we have a has_one relation!
$fields->removeByName('BackGroundImageID');
}
return $fields;
}
This will work...
$fields->removeByName('FieldName');

Grid Field not showing entries [SilverStripe]

I am using the MultiForm module to submit a long form with SilverStripe. The logic for this form is in 'CampaignBriefForm.php' whereas the gridfield CMS field is being added in 'CampaignBriefPage.php'. I have a Data Object for a CampaignBriefLead which is what the form creates.
Campaign Brief Page
private static $has_many = array(
'CampaignBriefLeads' => 'CampaignBriefLead'
);
public function CampaignBriefForm() {
return new CampaignBriefForm($this, 'CampaignBriefForm');
}
Campaign Brief Lead (DO)
private static $has_one = array( "Page" => "CampaignBriefPage" );
As you can see the Campaign Brief page has the correct relationship with the Data Object and also you can see the the form itself (done in a sepearate file) is correctly returning (as it's being saved in the DB). For some reason however, the gridfield will not show me what is in the database for that Data Object. The grid field code is as follows.
$fields = parent::getCMSFields();
$contactConfig = GridFieldConfig_RelationEditor::create();
$contactConfig->getComponentByType('GridFieldDataColumns')->setDisplayFields(
array(
'CompanyName' => 'Company Name',
'StartDate' => 'Start Date',
'Duration' => 'Duration',
'WebsiteURL' => 'Website',
'Budget' => 'Budget'
));
$contactGrid = new GridField(
'CampaignBrief',
'Campaign Enquiries',
$this->CampaignBriefLeads(),
$contactConfig
);
$fields->addFieldToTab("Root.Enquiries", $contactGrid);
To me this all looks correct and should work but for some reason it is not working.
Note
The link existing option on the gridfield allows me to link one of the entries from the DO with the gridfield weirdly?? So it saves one entry but I have to do it manually, this tells me it can see the DB but won't pull for some reason.
For reviewing reasons, here is the code for the multiform where the campaign brief lead is actually saved to the DB after the form is submitted.
public function finish($data, $form) {
parent::finish($data, $form);
$steps = DataObject::get(
'MultiFormStep',
"SessionID = {$this->session->ID}"
);
$enquiry = new CampaignBriefLead();
foreach($steps as $step) {
$data = $step->loadData();
foreach($data as $key => $value) {
if($key == 'url' || $key == 'MultiFormSessionID' || $key == 'action_finish') {
continue;
}
if(isset($data[$key])) {
$enquiry->$key = $data[$key];
error_log($data[$key]);
}
}
}
$enquiry->write();
$this->controller->redirect('/campaign-brief/');
}
If you need anything more let me know. Thanks.
I would take a guess that the CampaignBriefLead PageID is not being set on your form submission.
Check the CampaignBriefLead table in your database and check the PageID column. If it is blank, null or 0 for each row then it is not being set.
One way to fix this problem for any new submission is to set the PageID for the $enquiry:
public function finish($data, $form) {
// ...
$enquiry = new CampaignBriefLead();
if ($campaignBriefPage = CampaignBriefPage::get()->first()) {
$enquiry->PageID = $campaignBriefPage->ID;
}
// ...
}
For the existing entries you will need to update the entries to have the correct PageID.

Form don't submit

I do not understand how a form submission work in yii.Help me please...
public function actionHome() {
$model = new LoginForm;
$form = new CForm('application.views.website.formV', $model);
//protected/views/website/formV.php.
if($form->submitted('login') && $form->validate()){
echo 'nig';
$this->redirect(array('website/send'));
}
else {
$this->render('login', array('form'=>$form));
}
echo '<h1>Hello</h1>';
echo '<div class="form">';
echo $form;
echo '</div>';
}
FormV.php
return array(
'title'=>'Label title',
'elements'=>array(
'username'=>array(
'type'=>'text',
'maxlength'=>32,
),
'<div class="djada"></div>'
,
/*
'password'=>array(
'type'=>'password',
'maxlength'=>10,
),
*
*/
'rememberMe'=>array(
'type'=>'checkbox',
)
),
'buttons'=>array(
'login'=>array(
'type'=>'submit',
'label'=>'Enter',
),
),
);
When I click validation good but not redirect to 'website/send' ...
Another question is why the model is transmitted to new CForm...Why such a method?
How to work with it?
If you check LoginForm class in models directory, you will find that it holds 2 public variables which are required. Required variables are username and password. Since you have commented out the password element in the form builder you will not pass the following if statement.
if($form->submitted('login') && $form->validate()){
Reason why you are redirected to new form is because it is coded that way. Once submitted() and validate() functions return true you will be redirected to website/send action instead of new login form.
Please read http://www.yiiframework.com/doc/guide/1.1/en/form.builder for more information about the CForm class.

Remove tags in field on form submit in cakephp

I want to perform strip_tags on a field called description before data is saved in the database during form submission. I thought of creating a custom rule and doing it over there:
'description' => array(
'stripTags' =>array(
'rule' => array('StripTags'),
'message' => ''
),
),
public function StripTags($user = array()) {
return !empty($user['description'])?strip_tags($user['description']):"";
}
However this doesn't work since cakephp expects true/false to be returned instead of an updated value. How should I do this?
Use the Model::beforeSave() callback, that's were all automatic pre-save data modification logic should go. It is invoked before save, but after validation.
Untested example:
public function beforeSave($options = array())
{
if(!parent::beforeSave($options))
{
return false;
}
if(!empty($this->data[$this->alias]['description']))
{
$this->data[$this->alias]['description'] = strip_tags($this->data[$this->alias]['description']);
}
return true;
}

Zend Form Binding with Multiple Tables

In my Zend application i have separate models for each table and data is retrieved using TableGateway
Now i need to implement form to create edit page. I could able to create form of one table/model as mentioned in http://framework.zend.com/manual/2.2/en/user-guide/forms-and-actions.html
Here is my edit action -
public function editAction()
{
$id = (int) $this->params()->fromRoute('id', 0);
if (!$id) {
return $this->redirect()->toRoute('candidate', array(
'action' => 'index'
));
}
try {
$candidate = $this->getCandidateTable()->getCandidate($id);
}
catch (\Exception $ex) {
return $this->redirect()->toRoute('candidate', array(
'action' => 'index'
));
}
$form = new CandidateForm();
$form->bind($candidate);
$form->get('submit')->setAttribute('value', 'Edit');
$request = $this->getRequest();
if ($request->isPost()) {
$form->setInputFilter($candidate->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()) {
$this->getCandidateTable()->saveCandidate($candidate);
return $this->redirect()->toRoute('candidate');
}
}
return array(
'id' => $id,
'form' => $form,
);
}
edit view -
<?php
$title = 'Edit Candidate';
$this->headTitle($title);
?>
<h1><?php echo $this->escapeHtml($title); ?></h1>
<?php
$form = $this->form;
$form->setAttribute('action', $this->url(
'candidate',
array(
'action' => 'edit',
'id' => $this->id,
)
));
$form->prepare();
echo $this->form()->openTag($form);
echo $this->formHidden($form->get('id'));
echo $this->formRow($form->get('title'));
echo $this->formSubmit($form->get('submit'));
echo $this->form()->closeTag();
This edit action binds a form with one table (CandidateTable). But in my application, that page has data from multiple tables (CandidateSkills, CandidateQualifications etc). When i click submit it should save data in separate tables.
You can use setFromArray
You fetch the row object and than just setFromArray and save, commit.
To populate form value use populate method see this Populating and Retrieving Values
$form = new My_Form_Edit();
if( !$this->getRequest()->isPost() )// If the form isn't posted than populate the value
{
$form->populate($myArrayValueToPopulate);//$myArrayValueToPopulate this is your array to populate for the form
return;
}
// Than check validation and save data
For zend framework 2 you can use bind to populate data Binding an object
straight from documentation
When you bind() an object to the form, the following happens:
The composed Hydrator calls extract() on the object, and uses the values returned, if any, to populate the value attributes of all elements. If a form contains a fieldset that itself contains another fieldset, the form will recursively extract the values.
When isValid() is called, if setData() has not been previously set, the form uses the composed Hydrator to extract values from the object, and uses those during validation.
If isValid() is successful (and the bindOnValidate flag is enabled, which is true by default), then the Hydrator will be passed the validated values to use to hydrate the bound object. (If you do not want this behavior, call setBindOnValidate(FormInterface::BIND_MANUAL)).
If the object implements Zend\InputFilter\InputFilterAwareInterface, the input filter it composes will be used instead of the one composed on the form.
This is easier to understand in practice.
$contact = new ArrayObject;
$contact['subject'] = '[Contact Form] ';
$contact['message'] = 'Type your message here';
$form = new Contact\ContactForm;
$form->bind($contact); // form now has default values for
// 'subject' and 'message'
$data = array(
'name' => 'John Doe',
'email' => 'j.doe#example.tld',
'subject' => '[Contact Form] \'sup?',
);
$form->setData($data);
if ($form->isValid()) {
// $contact now looks like:
// array(
// 'name' => 'John Doe',
// 'email' => 'j.doe#example.tld',
// 'subject' => '[Contact Form] \'sup?',
// 'message' => 'Type your message here',
// )
// only as an ArrayObject
}

Categories