Troubleshooting dynamic dropdowns in SugarCRM 6.5 - php

I had asked a question here a while back about setting up database populated dropdowns for SugarCRM. I received a really good answer and, after more php studies and a dev instance running, I decided to give it a shot. The instructions I followed can be found here. After I run the repair and rebuild, I would expect to see the custom field in my Fields list under the module in studio, but have not been able to find it. The module is named Makers (a1_makers as a database table). For good orders sake, there were no errors when I repaired/rebuilt after saving the files. Per the instructions, I first created a php file with a custom function to query the database (custom/Extension/application/Ext/Utils/getMakers.php):
<?php
function getMakers() {
static $makers = null;
if (!$makers){
global $db;
$query = "SELECT id, name FROM a1_maker";
$result = $db->query($query, false);
$accounts = array();
$accounts[''] = '';
while (($row = $db->fetchByAssoc($result)) !=null) {
$accounts[$row['id']] = $row['name'];
}
}
return $makers;
}
?>
Then, I set 'function' field in Vardefs to point to the function (custom/Extension/modules/Maker/Ext/Vardefs/makers_template.php):
<?php
$dictionary['Maker']['fields']['list_of_makers'] = array (
'name' => 'list_of_makers',
'vname' => 'LBL_MKRLST'
'function' => 'getMakers',
'type' => 'enum',
'len' => '100',
'comment' => 'List of makers populated from the database',
);
?>
Unfortunately, there are no errors and the repair/rebuild runs fine. I am just unable to see the custom field when I go into studio. Can anyone please help point out what I may be doing wrong?

I would recommend checking existence of newly created field 'list_of_makers' in cache/modules/Maker/Makervardefs.php file. If new field definition exists in that file, try add 'studio' => 'visible' to custom/Extension/modules/Maker/Ext/Vardefs/makers_template.php to get something like this:
<?php
$dictionary['Maker']['fields']['list_of_makers'] = array (
'name' => 'list_of_makers',
'vname' => 'LBL_MKRLST'
'function' => 'getMakers',
'type' => 'enum',
'studio' => 'visible'
'len' => '100',
'comment' => 'List of makers populated from the database',
);
Try to edit your custom/modules/Maker/metadata/editviewdefs.php manually and insert field definition by hand in proper place if everything above won't work.

$dictionary['Maker']['fields']['list_of_makers'] = array (
'name' => 'list_of_makers',
'vname' => 'LBL_MKRLST'
'function' => 'getMakers',
'type' => 'enum',
'studio' => 'visible'
'len' => '100',
'comment' => 'List of makers populated from the database',
'studio' => array(
'listview' => true,
'detailview' => true,
'editview' => true
),
);

Related

Zend 2 Form Validator 'InArray' - Complicated array returning invalid

I am trying to implement the 'InArray' validator in Zend 2 on a form and it keeps on returning invalid. Here is the code:
The Form Element setup:
$enquiryType = new Element\Select('enquiryType');
$enquiryType->setLabel('* What is your enquiry about?')
->setLabelAttributes(array('class' => 'sq-form-question-title'))
->setAttribute('class', 'sq-form-field required')
->setValueOptions($enquiryTypes);
The Filter/Validator setup:
$enquiryType = new Input('enquiryType');
$enquiryType->getValidatorChain()
->addByName('InArray', array('haystack' => $enquiryTypes));
And here is the array that gets passed into $enquiryTypes via the module.config.php file
'enquiryCategories' => array(
'empty_option' => 'Please select an option',
array(
'label' => 'General enquiries',
'options' => array(
'skype' => 'Skype with your library feedback',
'question' => 'Ask a question',
'feedback' => 'Library feedback',
'eresource' => 'Electronic resources (e.g. e-book, e-journal, database)',
'webbridge' => 'WebBridge Problems',
'dro' => 'DRO'
)
),
array(
'label' => 'Application to review',
'options' => array(
'10400' => 'I\'ve returned the item',
'10401' => 'I didn\'t know about overdue points but now I have some',
'10402' => 'Why did I get this invoice?',
'10403' => 'The item I borrowed is lost',
'10404' => 'The item I borrowed has been damaged',
'10405' => 'I never got/had the book',
'10406' => 'Other'
)
)
),
I have tried different variations of this (using the recursive validation also) but have not been able to work this out.
One thing that I'd try, is as follows:
$enquiryType = new Input('enquiryType');
$enquiryType->getValidatorChain()
->addByName('InArray', array('haystack' => $enquiryTypes['enquiryCategories']));
The reason I say that, is that it looks like you might be creating an array inside of the array perhaps. Unless I've misunderstood the description.
If that isn't working for you then maybe you might need to explore the Explode option as pointed out in the following question
ZF2: How do I use InArray validator to validate Multiselect form element?
Good luck.
I finally got a working solution for this. I feel there should be a better solution but I could not find one.
Here is the filter I used:
$enquiryType = new Input('enquiryType');
$enquiryType->getValidatorChain()
->addByName('InArray', array('haystack' => array_keys(
$enquiryTypes[0]['options']+$enquiryTypes[1]['options']
)));
$enquiryType->getFilterChain()
->attach(new Filter\StringToLower())
->attachByName('StripTags');
Basically I had to disect the array options into a straight associative array. As the array remains static in this instance then this works well.
If the data becomes dynamic then something more would be required (loop through and find the 'option' key, add children to filter array etc...)

PHP/WordPress Get Users and Load into Plugin

This is my first question on StackOverflow! I'm a PHP and WP developer beginner, and I'm doing my best to learn and pull information together, but I'm stumped.
I'm using Ninja Forms for WordPress. I want to return a full list of users and have them display in the drop down selection. The code below is based off this: Foreach loop inside array.
$blogusers = get_users( array( 'fields' => array( 'user_email') ) );
$args = array(
'name' => 'Select User',
'edit_options' => array(
array(
'type' => 'select',
'name' => 'select_users_from_group',
'label' => 'Select a User',
'options' => array()
),
),
'display_function' => 'select_users_from_group',
'edit_function' => 'select_users_from_group_edit',
'sidebar' => 'template_fields'
);
foreach($blogusers as $key=>$user) {
$args['edit_options'][0]['options'][] = array(
// 'name' => $user=>user_email,;
);
}
if( function_exists( 'ninja_forms_register_field' ) ) {
ninja_forms_register_field('select_users_from_group', $args);
}
I know my foreach loop is no good, but I don't know what to do to make it work. It fails when I remove the comment.
Eventually, I'd like for another field to return a user_meta value based on the user selected here, but I have no idea where to even begin on that.
Any help is appreciated. Not looking for you to write it for me. I'd rather learn how it works. Thanks in advance!

Change subpanel order in SugarCRM 7

How can one change the order on each subpanel either by code or through the GUI?
In Sugar 6 the user could change the order simply by dragging and dropping the subpanels under each module.
From what I can see this is not possible in 7.x.
I have tried to change
'order' => 1
in
custom/Extension/modules/Opportunities/Ext/Layoutdefs/some_file.php
with no luck at all..
UPDATE:
As UTAlan stated,
this will become part of the stock functionality of Sugar starting in version 7.5.0: https://web.sugarcrm.com/support/issues/66590
Until then, here is the reason and the solution:
The 'order' => 1, does not seem to work on Sugar 7 at the moment.
Solution
Copy the file
modules/Opportunities/clients/base/layouts/subpanels/subpanels.php
to
custom/modules/Opportunities/clients/base/layouts/subpanels/subpanels.php
Now, add your custom subpanel definition to the beginning of the array or in any order you desire.
My example looks like this now:
$viewdefs['Opportunities']['base']['layout']['subpanels'] = array(
'components' => array(
// This is my custom module
array(
'layout' => 'subpanel',
'label' => 'LBL_OPPORTUNITIES_FOOBAR_TITLE',
'context' => array(
'link' => 'opportunities_foobar_1',
),
),
.. // Code ommited
array(
'layout' => 'subpanel',
'label' => 'LBL_EMAILS_SUBPANEL_TITLE',
'context' => array (
'link' => 'archived_emails',
),
),
),
'type' => 'subpanels',
'span' => 12,
);
Long Answer:
Why is 'order' => 1 not working anymore?
Inside include/MetaDataManager/MetaDataConverter.php:327:
public function toLegacySubpanelLayoutDefs(array $layoutDefs, SugarBean $bean) {
..
foreach ($layoutDefs as $order => $def) {
..
$return[$def['context']['link']] = array(
'order' => $order,
..
}
The order that is being rendered in the view is based on which order each bean-name is inserted inside the 'components'-key inside this file:
modules/Opportunities/clients/base/layouts/subpanels/subpanels.php
Core modules are hard-coded inside the subpanel file for Opportunities.
This will become part of the stock functionality of Sugar starting in version 7.5.0: https://web.sugarcrm.com/support/issues/66590

Query caching not working in Yii framework

I've a table containing more than 27,000 records. I want to fetch all data in Dropdown list. For that I've implemented cache but it seems to be not working as its getting very slow and showing blank page (Sometime browser is getting hanged).
Following is my code (I am using yiiboilerplate):
Configuration of backend/config/main.php in component array:
'cache' => array(
//'class' => 'system.caching.CMemCache',
'class' => 'system.caching.CDbCache',
'connectionID' => 'db',
),
In View page:
$dependency = new CDbCacheDependency('SELECT MAX(bank_id) FROM bank');
$bank = CHtml::listData(Bank::model()->cache(1000, $dependency)->findAll('is_active=1', array('order' => 'name')), 'bank_id', 'concatened');
echo $form->dropDownListRow($model, 'bank_id', $bank, array(
'empty' => 'Select'
));
I think 27000 records is not big data but still its getting very slow and I want to implement cache in my entire application.
Is my configuration correct? Where I am going wrong?
Thanks
I think your parameters in findAll is incorrect.
It should be:
Bank::model()
->cache(1000, $dependency)
->findAll([
'select' => 'bank_id',
'order' => 'name ASC', // if it is in ascending order
'condition' => 'is_active = 1'
]);
I don't know what concatened so I just ignored it. But you can always use scopes for your conditions.

Optimizing query with large result set

I have a CakePHP model, let's call it Thing which has an associated model called ItemView. ItemView represents one page view of the Thing item. I want to display how many times Thing has been viewed, so I do the following in my view:
<?php echo count($thing['ItemView']); ?>
This works, however as time goes on the result set of this query is going to get huge, as it's currently being returned like so:
array(
'Thing' => array(
'id' => '1',
'thing' => 'something'
),
'ItemView' => array(
(int) 0 => array(
'id' => '1',
'thing_id' => 1,
'created' => '2013-09-21 19:25:39',
'ip_address' => '127.0.0.1'
),
(int) 1 => array(
'id' => '1',
'thing_id' => 1,
'created' => '2013-09-21 19:25:41',
'ip_address' => '127.0.0.1'
),
// etc...
)
)
How can I adapt the model find() to retrieve something like so:
array(
'Thing' => array(
'id' => '1',
'thing' => 'something',
'views' => 2
)
)
without loading the entire ItemView relation into memory?
Thanks!
So it's pretty straight forward, we can make use of countercache - Cake does the counting for you whenever a record is added into/deleted fromItemView:
Nothing to change in your Thing.php model
Add a new INT column views in your things table.
In your ItemView.php model, add counterCache like this:
public $belongsTo = array(
'Thing' => array(
'counterCache' => 'views'
)
);
Then next time when you do addition/deletion via ItemView, Cake will automatically recalculate the counting and cache into views for you, so the next time when you do the query, you also need to make sure you specify recursive = -1 as what #Paco Car has suggested in his answer:
$this->Thing->recursive = -1;
$this->Thing->find(...); //this will returns array of Thing + the field "views"
// --- OR ---
$this->Thing->find(array(
'conditions' => array(
//... your usual conditions here
),
//... fields, order... etc
//this will make sure the recursive applies to this call, once only.
'recursive' => -1
);

Categories