In my form, I want to set the selected (default) value for a select element. However, using setDefaults is not working for me.
Here is my code:
$gender = new Zend_Form_Element_Select('sltGender');
$gender->setMultiOptions(array(
-1 => 'Gender',
0 => 'Female',
1 => 'Male'
))
->addValidator(new Zend_Validate_Int(), false)
->addValidator(new Zend_Validate_GreaterThan(-1), false);
$this->setDefaults(array(
'sltGender' => 0
));
$this->addElement($gender);
My controller is simply assigning the form to a view variable which just displays the form.
It works by using $gender->setValue(0), but it would be easier to set them all at once with an array of default values. Am I misunderstanding something here?
Also, where is the Zend Framework documentation for classes and methods? I am looking for something similar to the Java documentation. The best I could find is this one, but I don't like it - especially because every time I try to search, it crashes.
Have you tried:
$this->addElement($gender);
$this->setDefaults(array(
'sltGender' => 0
));
Also, take a look at http://framework.zend.com/issues/browse/ZF-12021 .
As you can see, the above issue is similar to the issue you're describing. It seems Zend is very particular about the order you create objects and assign settings.
I'm afraid you're going to have to do things in the order Zend wants you to do them (which doesn't seem well documented, but is only discovered thru trial and error), or hack their library to make it do what you want it to do.
Related
I have one view in Drupal 7, which displays user information like (Name, address, Status, etc..). I have one column in this (Table)view as "Published event". Basically events are created by users do I want to make this column sortable. I have attached image for more reference.
I tried with applying relationship but no success.
table settings
my handler code is like below :
$handler->display->display_options['sorts']['event_count_published'] ['id'] = 'event_count_published';
$handler->display->display_options['sorts']['event_count_published'] ['table'] = 'search_api_index_user_search_index';
$handler->display->display_options['sorts']['event_count_published'] ['field'] = 'event_count_published';
$handler->display->display_options['sorts']['event_count_published'] ['order'] = 'DESC';
'mail' => array(
'sortable' => 1,
'default_sort_order' => 'asc',
'align' => '',
'separator' => '',
'empty_column' => 0,
),
'event_count_published' => array(
'align' => '',
'separator' => '',
'empty_column' => 0,
'sortable' => 1,
),
above code is in "tcd_reporting.views_default.inc" file, if I put 'sortable => 1', it still does not provide sorting
field is created by below code:
$properties['event_count_published'] = array(
'label' => t('Published Events'),
'description' => t('Number of published events authored by user.'),
'type' => 'integer',
'getter callback' => 'tcd_event_content_type_count_published_get',
'computed' => TRUE,
'entity views field' => TRUE,
);
[Introduction] Which function is responsible for 'click sort' in views?
Click sort -this checkbox from your second screen- in views table settings is function which is enabled only for fields which have properly defined handlers. As you may know each field in views have few handlers (for displaying, filtering, sorting). And for click sort to be possible on specified column its field handler must have two functions defined: click_sortable and click_sort. First one just need to return true, while second need to properly implements sorting on view. For example see handler: [views_module_path]/handlers/views_handler_field.inc.
Your case:
It seems that your column "Published event" have defined handler which does not have click_sortable and click_sort functions (or click_sortable simply returns false).
Possible fix:
Find place where you defined your view source (it depends on how you informed views about it, if I understand its something like "User info" - maybe in hook_entity_info function or hook_views_data function), check what handler is assigned to your "Published event" field and change it.
It's hard to tell where you need to look as it depends on your implementation.
I suggest you to try create hook_views_data_alter function and dpm() it for start. Later you can alter it like that:
mymodule_views_data_alter(&$data) {
$data['some_view_info']['published_event']['field']['handler'] = 'views_handler_field_numeric';
}
Edit 1
First could you tell where this code is? Is it inside handler class, or maybe some views hook? Views gives you a lot of flexibility but this make them hard to understand, and I'm not sure what exactly you achieve and how.
Assuming your field works properly you can try to simply enable click sort.
Example: I created hook_views_data_alter function to see content of views data
function mymodule_views_data_alter(&$data) {
dpm($data,'d');
}
You might need to clear cache to see dpm of *_alter hooks.
Inside dpm'ed array I found "users" for generic example, and its field name looks like this:
I suggest you to try alter your field with click_sortable = TRUE and see what happens. If this wont help please provide more information about your field, how you created it, how it looks in hook_views_data_alter and which handlers it has defined.
Edit 2
Ok, so you have your views exported to code into views_default file. But this only allows you to export view you created from database to code, so it is basically a reflection of what you done in views web editor (eg. page yourwebsite.com/admin/structure/views/view/your_view_name/edit). What you need to do is to change behavior of one of your fields so it became sortable (add click_sortable and click_sort functions in handler class) or change handler of this field to one with sorting option (change field handler to other one like views_handler_field_numeric). If you don't have experience in creating handlers and this is one of generic handlers i suggest you to go back to my Edit 1, examine your dpm, and try to alter $data array to find solution.
Edit 3
Little explanation to prevent confusion. When creating new view you select collection on which this particular view base on (simpliest example - it may be MySQL table, and view will use SQL queries to retrieve data from it). By digging down we have:
Collection - eg. User which is database table user, it is what you select as source when creating new view.
Field - eg. mail which is database column mail, this fields you add to your view.
Field handler - eg. views_handler_field_numeric, this is class name of handler to use by specified field
Now, if you don't created your own handler then your field "Published event" have one of generic views handler. You shouldn't ever change code of contributed modules - especially so widely used as views handlers. That's why my suggestion to add functions click_sortable and click_sort is incorrect. Instead you should change handler responsible for field "Published event".
Best way is to define proper handler in place where you define your field "Published event". If it's somehow impossible the only way I can think of is hook_views_data_alter see docs for more info and examples. I suppose you should try to redefine handler of your field to generic numeric handler views_handler_field_numeric as it should have full sorting functionallity, or try to add click_sortable property to field array as you can see in first image of my post, but I can't provide you fully tested example.
I got stuck with this stupid error messages in Zend Framework 2. Spent two hours and nothing, I still got two different error messages with NotEmpty validator.
$nameNotEmptyMessage = 'Pole wymagane';
$inputFilter->add(array(
'name' => 'name',
'required' => true,
'filters' => array(
new Filter\StringTrim()
),
'validators' => array(
new Validator\NotEmpty(array(
'messages' => array(
Validator\NotEmpty::INVALID => $nameNotEmptyMessage,
Validator\NotEmpty::IS_EMPTY => $nameNotEmptyMessage
)
))
)
));
And what? It works pretty cool when I send form with "name" element inside it. When it's empty, I've got my message. But, when I send form without the "name" element inside it, the message is still "Value is required and can't be empty"! Why?
I need to have in both cases the same message because sometimes the form won't have "name" element.
Thank you guys very much!
Thanks for replying to the comment to clarify the problem. First I must say, I feel your pain on this one. After having not used ZF2 for over a year and spending some time figuring this out, it highlights yet another painful thing in ZF2.
That said, here is my simple solution. Not necessary correct, or the best way to go about it but it solves your problem with the least amount of code. In your controller where you instantiate and validate the form, add this code before you call new Form:
if (!isset($_POST['name'])) {
$this->getRequest()
->setPost(
new \Zend\Stdlib\Parameters(
array('name' => '')
)
);
}
This seemed the simplest route rather than setting up a default validation translator and adding a duplicate message. It is just checking to see if the name field was not present, and if so sets it with any empty value.
Now the reason why we have to do this:
This happens because of how \Zend\InputFilter\Input works. When the InputFilter runs, it sees the element is missing. It then checks the required property, sees it's true but the input has no value. No value being different than empty.
When the filter is required but has no input, \Zend\InputFilter\Input::prepareRequiredValidationFailureMessage is called. If you look at the source of that function, you'll see:
protected function prepareRequiredValidationFailureMessage()
{
$notEmpty = new NotEmpty();
$templates = $notEmpty->getOption('messageTemplates');
return [
NotEmpty::IS_EMPTY => $templates[NotEmpty::IS_EMPTY],
];
}
Notice how it creates a new NotEmpty validator and fetches its default message, thus bypassing the translation you set within the InputFilter.
The alternative:
One alternative, which may be more correct, but also requires more code and could arguably be more confusing looking back later would be to create a new class implementing \Zend\Validator\Translator\TranslatorInterface and set an array with the translation for that message and then calling \Zend\Validator\AbstractValidator::setDefaultTranslator passing that so the default translator will be used on that message.
This is just difficult because there is no short way of setting up that object because of how the classes are inherited and I wasn't able to find a quick solution to set up the default translator with just that message. Also, if you have another translator in place, it might interfere with it.
So it seems the simplest thing is to just check for the absence of that form field and populate it with any empty value if it's missing.
Hope that helps!
Other more simple way to fix this is to overwrite the Form setData($data) and to check if $data['name'] is set. Something like this:
public function setData($data)
{
if(!isset($data['name'])){
$data['name'] = '';
}
return parent::setData($data);
}
I'm a little bit stuck with this: I have a controller where I'm collecting all available languages for an object in pimcore.
Right now I simply take a Localized Field from that object, run through it via foreach and fill an array with the Localized Fields's keys. So I get all languages for that object. But this is the most ugly piece I've ever coded :)
Update - here is the code:
$o = Object_Product::getById(SOME_ID);
$availableLanguages = array();
// 'category' is an attribute of my product-object that uses Localized Fields
foreach ($o->getCategory()->getLocalizedfields()->getItems() as $language => $value) {
$availableLanguages[] = $language;
}
So I get an array that looks like:
$availableLanguages(
0 => 'en',
1 => 'de',
2 => 'it'
// etc.
);
I'm afraid I've thought too much about it and now I'm missing the forest for the trees - there must be an (more) elegant way for this. Basically Zend_Locale should have this info too, but I don't get it.
Does anyone have a clue for me? Thanks in advance!
Getting all available languages (enabled translations) in Pimcore:
Starting from Pimcore 6.9 and in currently available Pimcore 10 we use:
$languages = \Pimcore\Tool::getValidLanguages();
The documentation is here https://pimcore.com/docs/pimcore/current/Development_Documentation/Objects/Object_Classes/Data_Types/Localized_Fields.html
As I see in the original question, the author is creating some export for DataObject with all available translations.
In such case we need to disable Fallback languages:
\Pimcore\Model\DataObject\Localizedfield::setGetFallbackValues(false);
This will allow us to get an empty value for fieds without translation instead of default language value.
After crawling through tons of pimcore-backend-Classes I found the solution here:
$config = \Zend_Registry::get("pimcore_config_system");
$validLanguages = strval($config->general->validLanguages);
I'm trying to find the way laravel 4 works with array data in requests but can't find any example, tutorials, documentation about it on the net.
Example:
<select name="productDetails[0][service]">...</select>
<select name="productDetails[0][product]">...</select>
<select name="productDetails[0][action]">...</select>
<select name="productDetails[1][service]">...</select>
<select name="productDetails[1][product]">...</select>
<select name="productDetails[1][action]">...</select>
Ends up being:
$_GET['productDetails'][0]['service']
$_GET['productDetails'][0]['product']
$_GET['productDetails'][0]['action']
$_GET['productDetails'][1]['service']
$_GET['productDetails'][1]['product']
$_GET['productDetails'][1]['action']
Now if i want to make my form work correctly i have the read this data, but i can't assume that productDetails is an array and features 0. I want to use the facilities provided by Laravel/Symfony's HTTP Foundation components.
I tried without avail:
Request::get('productDetails.0.service', null); //Doesn't work
Request::get('productDetails[0][service]', null); //Doesn't work
Request::get('productDetails.1.service', null); //Doesn't work
Request::get('productDetails[1][service]', null); //Doesn't work
I thought these versions would work because you can access session, config and probably many other data sources like this. Just stumped that this doesn't work... On the other hand, this following snippet works, but it's ugly cause you can't assume productDetails is an array at all times, you also can't assume 0 index exists nor "service" index too...
Request::get('productDetails', array())[0]['service']; //Works but ugly
Request::get('productDetails', array())[1]['service']; //Works but ugly
So what is the right way to accomplish this?
Edit #1
Added symfony to the tags, and i realize now that the Request object from Laravel really is an HTTPFoundation from symfony, so how do these guys work with all this? Am i the only one? I'm sure it's just a matter of naming conventions, i might not be using the right terms to search my documentation
Ahhhhh finaly found it:
Request::query('productDetails[0]', array()); //array('service' => 2, 'product' => null, 'action' => null);
Request::query('productDetails[1]', array()); //array('service' => 3, 'product' => null, 'action' => null);
Request::query('productDetails[0][service]', array()); //2
Request::query('productDetails[1][service]', array()); //3
Had to dig a little in the Request class and Symfony HTTPFoundation but was able to find examples and codes down there that explained how it worked.
Hope this helps others...
Any reason not to switch them to be separate inputs?
<select name="productDetailService">...</select>
<select name="productDetailsProduct">...</select>
<select name="productDetailsAction">...</select>
As I'm sure you realize, that would mean processing each one in separately in your form processing code.
However, if you aren't trying to make a form where you need to add new productDetails fields ad-hoc, I don't see a reason to make the code more confusing by using arrays in that way - processing each one separately or treating them as separate fields (vs an aggregate within an array) might be the better way to go.
I want to save an object or form to the database. Only I can't find the easiest (or normal) way for how to do this.
I found a lot of tutorials, but none seem to be easy or current. Can someone please help me with this?
I use version 1.9.3 of the Zend Framework.
The easiest way (aka the way using the smallest amount of code) to insert a row into a database table using Zend_Db is:
$data = array(
'created_on' => '2007-03-22',
'bug_description' => 'Something wrong',
'bug_status' => 'NEW'
);
$db->insert('bugs', $data);
The above code will insert a new row into the bugs table whereas $db is the Zend_Db_Adapter_Abstract-subclass you created with Zend_Db::factory(). Please see Writing Changes to the Database in the Zend Framework manual for more details and the whole spectrum of features Zend_Db provides.
For the sake of completeness, the above code will issue a query to the database similar to:
INSERT INTO bugs (created_on, bug_description, bug_status)
VALUES ('2007-03-22', 'Something wrong', 'NEW')
The next step would be a more sophisticated approach using Zend_Db_Table.
EDIT:
Given that you have a Zend_Form ($form) with the appropriate fields created_on, bug_description and bug_status and provided that you have the right filters and validators in place, adding a new row with values given in the form is as easy as
if ($form->isValid($_POST)) {
$db->insert('bugs', $form->getValues());
}
Storing a custom object is also very easy:
// $bug is your custom object representing a bug
$db->insert('bugs', array(
'created_on' => $bug->getCreatedOn(),
'bug_description' => $bug->getDescription(),
'bug_status' => $bug->getStatus()
));
Instantiate any object that you need and serialize it. Once serialized, you can store it or transmit it to pretty much any medium. Is this what you are referring to?