Hot to use variable in query in Drupal 8? - drupal-8

I have this code:
function my_module_test($key_make = '') {
$db = new mysqli('xxx', 'xxx', 'xxx', "xxx");
mysqli_set_charset($db, "UTF8");
if ($key_make) {
$sql_model = "SELECT * FROM `car_model` WHERE `id_car_make` = ('$key_make')";
$res_model = $db->query($sql_model) or die(mysqli_error($db));
while ($row = mysqli_fetch_object($res_model)) {
$Key_model = $row->id_car_model;
$Model_value = $row->name;
$dropdown_model[$Key_model] = $Model_value;
}
}
return $dropdown_model;
}
How can I pass the value of the variable $key_make in WHERE clausole ?

The query function takes a second parameter with an array of replacement values, so you would do it like this:
$sql_model = "SELECT * FROM {car_model} WHERE id_car_make = :make";
$res_model = $db->query($sql_model, [':make' => $key_make]);
Static queries are documented here
You could also use a dynamic query (documented here):
$query = $db->select('car_model', 'cm');
$query->fields('cm');
$query->condition('cm.id_car_make', $key_make);
$res_model = $query->execute();
But...
if your "car_model"s are custom entities (which they should be as you will get many benefits like views integration), you should probably use an entityQuery

First you need to use the Drupal Database API to connect to a database. So my final code is the following and it works.
function car2db_model_dropdown_options($key_make) {
$connection = Database::getConnection('default', 'migrate');
$dropdown_model = ['_none'=>'Select'];
$key_make = (int)$key_make;
$sql_model = "SELECT * FROM car_model WHERE id_car_make = :make";
$query = $connection->query($sql_model, [':make' => $key_make]);
$result = $query->fetchAll();
foreach ($result as $row) {
$Key_model = $row->id_car_model;
$Model_value = $row->name;
$dropdown_model[$Key_model] = $Model_value;
}
return $dropdown_model;
}

Related

Search in agresso Query Engine

Is it possible to search/filter on columns with Agresso's QueryEngineService? I've been playing around with SearchCriteria.SearchCriteriaPropertiesList and TemplateResultOptions.Filter but without any luck. I havn't been able to locate any documentation on this matter either.
QueryEngineService.TemplateList templateList = QueryEngineService.GetTemplateList(null, null, Credentials);
var template = templateList.TemplateHeaderList.FirstOrDefault(x => x.Name == strViewName);
if (template == null)
return null;
QueryEngineService.SearchCriteria searchProp = QueryEngineService.GetSearchCriteria(template.TemplateId, false, Credentials);
QueryEngineService.TemplateResultOptions options = QueryEngineService.GetTemplateResultOptions(Credentials);
options.RemoveHiddenColumns = true;
QueryEngineService.InputForTemplateResult input = new QueryEngineService.InputForTemplateResult();
input.TemplateResultOptions = options;
input.TemplateId = template.TemplateId;
input.SearchCriteriaPropertiesList = searchProp.SearchCriteriaPropertiesList;
QueryEngineService.TemplateResultAsDataSet result = QueryEngineService.GetTemplateResultAsDataSet(input, Credentials);
return result.TemplateResult;
You can try to start with this:
List<SearchCriteriaProperties> searchCriteriaProperties = searchCriteria.getSearchCriteriaPropertiesList().getSearchCriteriaProperties();
SearchCriteriaProperties columnFilter = null;
for (SearchCriteriaProperties criteria : searchCriteriaProperties) {
if(criteria.getColumnName().equalsIgnoreCase("ColumnNameHere")) {
columnFilter = criteria;
columnFilter.setRestrictionType("=");
columnFilter.setFromValue("valueToAssign");
}
}
Next is add the columnFilter variable to an instance of the ArrayOfSearchCriteriaProperties() object by using the getSearchCriteriaProperties().add()
ArrayOfSearchCriteriaProperties filter = new ArrayOfSearchCriteriaProperties();
filter.getSearchCriteriaProperties().add(columnFilter);
You can now add the filter object to an instance of the InputForTemplateResult() object.
Working solution (for me)
QueryEngineService.SearchCriteria searchProp = QueryEngineService.GetSearchCriteria(template.TemplateId, false, Credentials);
foreach (QueryEngineService.SearchCriteriaProperties criteria in searchProp.SearchCriteriaPropertiesList)
{
if(criteria.ColumnName.Equals("column_name", StringComparison.OrdinalIgnoreCase))
{
criteria.RestrictionType = "=";
criteria.FromValue = "value";
}
}
//Rest of the code from question above

SPAlert.Filter not working

Can anybody help with SPAlert filters on Sharepoint 2013?
If I set Filter property on SPAlert instance the alert has not been sent
SPAlert newAlert = user.Alerts.Add();
SPAlertTemplateCollection alertTemplates = new SPAlertTemplateCollection(
(SPWebService)(SPContext.Current.Site.WebApplication.Parent));
newAlert.AlertType = SPAlertType.List;
newAlert.List = list;
newAlert.Title = alertTitle;
newAlert.DeliveryChannels = SPAlertDeliveryChannels.Email;
newAlert.EventType = eventType;
newAlert.AlertFrequency = SPAlertFrequency.Immediate;
newAlert.AlertTemplate = alertTemplates[Constants.AlertTemplates.GenericListCustom];
var wsm = new WorkflowServicesManager(web);
var wss = wsm.GetWorkflowSubscriptionService();
var subscriptions = wss.EnumerateSubscriptionsByList(list.ID);
bool assotiationExist = false;
var guid = Constants.Workflows.ApprovalWF.Guid;
foreach (var subs in subscriptions)
{
assotiationExist = subs.DefinitionId == guid;
if (assotiationExist)
{
newAlert.Filter = "<Query><Eq><FieldRef Name=\"ApprovalStatus\"/><Value type=\"string\">Approved</Value></Eq></Query>";
}
}
newAlert.Update(false);
If I set Filter property on SPAlert instance the alert has not been sent
What do you need exactly ?
If you just want to change the filter (alert condition), did you simply try :
newAlert.AlertType = SPAlertType.List;
newAlert.List = list;
newAlert.Title = alertTitle;
newAlert.DeliveryChannels = SPAlertDeliveryChannels.Email;
newAlert.EventType = eventType;
newAlert.AlertFrequency = SPAlertFrequency.Immediate;
newAlert.AlertTemplate = alertTemplates[Constants.AlertTemplates.GenericListCustom];
newAlert.Filter = "<Query><Eq><FieldRef Name=\"ApprovalStatus/New\"/><Value type=\"string\">Approved</Value></Eq></Query>";
newAlert.Update(false);
I have just added a /New in your filter query. Query filter in alert need to get a /New or a /Old in your field.
If your alert still doesn't work, it might be something else than the filter.
The problem was in line newAlert.EventType = eventType. eventType was SPEventType.Add. That was the reason of not sending alert after Workflow set the ApprovalStatus field to «Approved».
I’ve modified algourithm. Now eventType is SPEventType.Modify and I added new field "IsNewAlertSent" to list. When event fires the first time then I send email and set the "IsNewAlertSent" field
Final code is shown below.
class UserAlertManager:
..
newAlert.EventType = (eventType == SPEventType.Add? SPEventType.Modify: eventType);
newAlert.AlertFrequency = SPAlertFrequency.Immediate;
newAlert.AlertTemplate = alertTemplates[Constants.AlertTemplates.GenericListCustom];
..
if (assotiationExist)
{
newAlert.Filter = "<Query><Eq><FieldRef name=\"ApprovalStatus\"/><Value type=\"Text\">Approved</Value></Eq></Query>";
newAlert.Properties.Add("grcustomalert", "1");
}
..
newAlert.Update(false);
class GRCustomAlertHandler:
...
string subject = string.Empty;
string body = string.Empty;
bool grCustomAlert = Utils.IsSPAlertCustom(ahp.a);
if (ahp.eventData[0].eventType == (int)SPEventType.Modify && grCustomAlert)
{
SPListItem item = list.GetItemById(ahp.eventData[0].itemId);
var isNewAlertSentField = item.Fields.GetFieldByInternalName(Constants.Fields.IsNewAlertSent);
if (isNewAlertSentField != null && (item[Constants.Fields.IsNewAlertSent] == null || !(bool)item[Constants.Fields.IsNewAlertSent]))
{
...
Utils.SendMail(web, new List<string> { ahp.headers["to"].ToString() }, subject, body);
item[Constants.Fields.IsNewAlertSent] = true;
using (new DisabledItemEventScope())
{
item.SystemUpdate(false);
}
}
}
...

I made module for vtiger 6.5 but it is not showing.

language and module file path
vtiger/language/en_us/Expenses.php
vtiger/modules/Expenses/Expenses.php
both file are same.
include_once 'modules/Vtiger/CRMEntity.php';
class Expenses extends Vtiger_CRMEntity {
var $table_name = 'vtiger_expenses';
var $table_index= 'expensesid';
var $customFieldTable = Array('vtiger_expensescf', 'expensesid');
var $tab_name = Array('vtiger_crmentity', 'vtiger_expenses', 'vtiger_expensescf');
var $tab_name_index = Array(
'vtiger_crmentity' => 'crmid',
'vtiger_expenses' => 'expensesid',
'vtiger_expensescf'=>'expensesid');
var $list_fields = Array (
/* Format: Field Label => Array(tablename, columnname) */
// tablename should not have prefix 'vtiger_'
'Summary' => Array('expenses', 'summary'),
'Assigned To' => Array('crmentity','smownerid')
);
var $list_fields_name = Array (
/* Format: Field Label => fieldname */
'Summary' => 'summary',
'Assigned To' => 'assigned_user_id',
);
// Make the field link to detail view
var $list_link_field = 'summary';
// For Popup listview and UI type support
var $search_fields = Array(
/* Format: Field Label => Array(tablename, columnname) */
// tablename should not have prefix 'vtiger_'
'Summary' => Array('expenses', 'summary'),
'Assigned To' => Array('vtiger_crmentity','assigned_user_id'),
);
var $search_fields_name = Array (
/* Format: Field Label => fieldname */
'Summary' => 'summary',
'Assigned To' => 'assigned_user_id',
);
// For Popup window record selection
var $popup_fields = Array ('summary');
// For Alphabetical search
var $def_basicsearch_col = 'summary';
// Column value to use on detail view record text display
var $def_detailview_recname = 'summary';
// Used when enabling/disabling the mandatory fields for the module.
// Refers to vtiger_field.fieldname values.
var $mandatory_fields = Array('summary','assigned_user_id');
var $default_order_by = 'summary';
var $default_sort_order='ASC';
}
root file
vtiger/Expenses.php
include_once 'vtlib/Vtiger/Module.php';
$Vtiger_Utils_Log = true;
$MODULENAME = 'Expenses';
$moduleInstance = Vtiger_Module::getInstance($MODULENAME);
if ($moduleInstance || file_exists('modules/'.$MODULENAME)) {
echo "Module already present - choose a different name.";
} else {
$moduleInstance = new Vtiger_Module();
$moduleInstance->name = $MODULENAME;
$moduleInstance->parent= 'Tools';
$moduleInstance->save();
// Schema Setup
$moduleInstance->initTables();
// Field Setup
$block = new Vtiger_Block();
$block->label = 'LBL_'. strtoupper($moduleInstance->name) . '_INFORMATION';
$moduleInstance->addBlock($block);
$blockcf = new Vtiger_Block();
$blockcf->label = 'LBL_CUSTOM_INFORMATION';
$moduleInstance->addBlock($blockcf);
$field1 = new Vtiger_Field();
$field1->name = 'summary';
$field1->label= 'Summary';
$field1->uitype= 2;
$field1->column = $field1->name;
$field1->columntype = 'VARCHAR(255)';
$field1->typeofdata = 'V~M';
$block->addField($field1);
$moduleInstance->setEntityIdentifier($field1);
$field2 = new Vtiger_Field();
$field2->name = 'expenseon';
$field2->label= 'Expense On';
$field2->uitype= 5;
$field2->column = $field2->name;
$field2->columntype = 'Date';
$field2->typeofdata = 'D~O';
$block->addField($field2);
$field3 = new Vtiger_Field();
$field3->name = 'expenseamount';
$field3->label= 'Amount';
$field3->uitype= 71;
$field3->column = $field3->name;
$field3->columntype = 'VARCHAR(255)';
$field3->typeofdata = 'V~M';
$block->addField($field3);
$field3 = new Vtiger_Field();
$field3->name = 'description';
$field3->label= 'Description';
$field3->uitype= 19;
$field3->column = 'description';
$field3->table = 'vtiger_crmentity';
$blockcf->addField($field3);
// Recommended common fields every Entity module should have (linked to core table)
$mfield1 = new Vtiger_Field();
$mfield1->name = 'assigned_user_id';
$mfield1->label = 'Assigned To';
$mfield1->table = 'vtiger_crmentity';
$mfield1->column = 'smownerid';
$mfield1->uitype = 53;
$mfield1->typeofdata = 'V~M';
$block->addField($mfield1);
$mfield2 = new Vtiger_Field();
$mfield2->name = 'CreatedTime';
$mfield2->label= 'Created Time';
$mfield2->table = 'vtiger_crmentity';
$mfield2->column = 'createdtime';
$mfield2->uitype = 70;
$mfield2->typeofdata = 'T~O';
$mfield2->displaytype= 2;
$block->addField($mfield2);
$mfield3 = new Vtiger_Field();
$mfield3->name = 'ModifiedTime';
$mfield3->label= 'Modified Time';
$mfield3->table = 'vtiger_crmentity';
$mfield3->column = 'modifiedtime';
$mfield3->uitype = 70;
$mfield3->typeofdata = 'T~O';
$mfield3->displaytype= 2;
$block->addField($mfield3);
// Filter Setup
$filter1 = new Vtiger_Filter();
$filter1->name = 'All';
$filter1->isdefault = true;
$moduleInstance->addFilter($filter1);
$filter1->addField($field1)->addField($field2, 1)->addField($field3, 2)->addField($mfield1, 3);
// Sharing Access Setup
$moduleInstance->setDefaultSharing();
// Webservice Setup
$moduleInstance->initWebservice();
mkdir('modules/'.$MODULENAME);
echo "OK\n";
}
//
language and module file path
vtiger/language/en_us/Expenses.php
vtiger/modules/Expenses/Expenses.php
both file are same.
//
Have you run the file which you have created in root directory(vtiger/Expenses.php) of CRM.
You have to run this file from browser.
http://localhost/vtiger/Expenses.php
There is no issue in your script file you have created.
Best method for creating module as below:
For Windows:
- Just open command line
- go in www/html/vtigercrm/vtlib/tools directory and run php -f console.php command.
- Now Enter your module name and refresh you crm and click on all will display your module
For Linux:
- Just open Terminal
- Go in cd var/www/html/vtigercrm/vtlib/tools directory
- Run php -f console.php command.
- It will display like
user#user:~$ cd /var/www/html/vtigercrm/vtlib/tools
user#user:/var/www/html/vtigercrm/vtlib/tools$ php -f console.php
Welcome to Vtiger CRM Creator.
This tool will enable you to get started with developing extensions with ease.
Have a good time. Press CTRL+C to "quit".
Choose the options below:
1. Create New Module.
2. Create New Layout.
3. Create New Language Pack.
4. Create Test Language Pack.
5. Import Module.
6. Update Module.
7. Remove Module.
Enter your choice:
- Enter 1
- Enter name of module
- Now refresh crm and click on all menu, you can see your module

Zend Regex route reverse with paginator

I have following regex route, which allows me to use pagination - to parse URL and also build it:
; route "product-{brand}"
product.type = "Zend_Controller_Router_Route_Regex"
product.route = "product-([a-z\-]+)(?:/page/(\d+)/?)?"
product.defaults.module = "default"
product.defaults.controller = "products"
product.defaults.action = "product"
product.defaults.page = "1"
product.map.1 = "brand"
product.map.2 = "page"
product.reverse = "product-%s/page/%d"
Everything is working fine, however, I need to get the rid of default page. Currently we are migrating old web to the Zend and we need to preserve old links because of current google positions, etc.
With default "page", I'm getting always /page/1, without it Zend "cannot assemble" URL.
How to not display page 1 in URL ?
Finally, I've managed to achieve this, but only by rewriting Regex assemble method.
I'm simply overriding two methods.
Class extension:
class Utils_Router_Regex extends Zend_Controller_Router_Route_Regex
{
// instantiate
public static function getInstance(Zend_Config $config)
{
$defs = ($config->defaults instanceof Zend_Config) ? $config->defaults->toArray() : array();
$map = ($config->map instanceof Zend_Config) ? $config->map->toArray() : array();
$reverse = (isset($config->reverse)) ? $config->reverse : null;
return new self($config->route, $defs, $map, $reverse);
}
// in this case, we are using $this->_reverse as array from config
public function assemble($data = array(), $reset = false, $encode = false, $partial = false)
{
//// EXTENSION PART !!!
if( !isset( $data[(string) $this->_reverse->pagemap]) ) { // if not set url helper
$reverse = $this->_reverse->base;
} else { // if set in url helper
$reverse = $this->_reverse->paginator;
}
/// end of extension part
if ($reverse === null) {
require_once 'Zend/Controller/Router/Exception.php';
throw new Zend_Controller_Router_Exception('Cannot assemble. Reversed route is not specified.');
}
$defaultValuesMapped = $this->_getMappedValues($this->_defaults, true, false);
$matchedValuesMapped = $this->_getMappedValues($this->_values, true, false);
$dataValuesMapped = $this->_getMappedValues($data, true, false);
// handle resets, if so requested (By null value) to do so
if (($resetKeys = array_search(null, $dataValuesMapped, true)) !== false) {
foreach ((array) $resetKeys as $resetKey) {
if (isset($matchedValuesMapped[$resetKey])) {
unset($matchedValuesMapped[$resetKey]);
unset($dataValuesMapped[$resetKey]);
}
}
}
// merge all the data together, first defaults, then values matched, then supplied
$mergedData = $defaultValuesMapped;
$mergedData = $this->_arrayMergeNumericKeys($mergedData, $matchedValuesMapped);
$mergedData = $this->_arrayMergeNumericKeys($mergedData, $dataValuesMapped);
if ($encode) {
foreach ($mergedData as $key => &$value) {
$value = urlencode($value);
}
}
ksort($mergedData);
$return = #vsprintf($reverse, $mergedData);
if ($return === false) {
require_once 'Zend/Controller/Router/Exception.php';
throw new Zend_Controller_Router_Exception('Cannot assemble. Too few arguments?');
}
return $return;
}
}
Then you can define which sprintf string to use:
hodinky.type = "Utils_Router_Regex"
hodinky.route = "hodinky-([a-z\-]+)(?:/page/(\d+)/?)?"
hodinky.defaults.module = "default"
hodinky.defaults.controller = "products"
hodinky.defaults.action = "hodinky"
hodinky.map.1 = "znacka"
hodinky.map.2 = "page"
hodinky.reverse.paginator = "hodinky-%s/page/%d" ; assebmly with paginator
hodinky.reverse.base = "hodinky-%s/" ; assebmly without paginator
hodinky.reverse.pagemap = "page" ; "page" map key
If you have better solution, please let me know.

Group Events by Week Commencing in Eloquent

I have the following method in my Event model for my events:
public static function getEvents($perPage = 10)
{
$events = Event::where('active', '=', 1)->paginate($perPage);
return $events;
}
Each event has a start_date and I need to take that start date and group the results in the view by week commencing, as in the Monday of the week each event occurs. I have this in my controller:
public function index()
{
$events = Event::getEvents($perPage = 5);
$this->layout->content = View::make('events.index')->with('events', $events);
}
Can anyone help me out with grouping these events by week commencing? Thanks.
I'm part way there in terms of getting the week commencing date using:
foreach ($events as $event)
{
$start_date = DateTime::createFromFormat('Y-m-d', $event->start_date);
$week = $start_date->format('YW');
$monday = 1;
$day_offset = ($monday - $start_date->format('N'));
$week_commencing = $start_date->modify("$day_offset days");
$week_commencing = $week_commencing->format('jS F Y');
}
Now I just need to use that to group the events but I'm not sure how to.
EDIT: I feel I'm getting closer to a solution but still need a little help. I now have the below in my controller, and it does print out 1 week commencing then all the events but when var_dump(ing) the $events->weeks_commencing there is only 1 date in the object, so I'm nearly there. Any pointers guys?:
foreach ($events as $event)
{
$start_date = DateTime::createFromFormat('Y-m-d', $event->start_date);
$week = $start_date->format('YW');
$monday = 1;
$day_offset = ($monday - $start_date->format('N'));
$week_commencing = $start_date->modify("$day_offset days");
if (!array_key_exists($week, $events))
{
$events->weeks_commencing = (object) array(
'week' => $week_commencing->format('jS F Y')
);
}
}
EDIT: OK I now have this in my controller. It's getting closer but not quite right yet.
foreach ($events as $event)
{
$start_date = DateTime::createFromFormat('Y-m-d', $event->start_date);
$week = $start_date->format('YW');
$monday = 1;
$day_offset = ($monday - $start_date->format('N'));
$week_commencing = $start_date->modify("$day_offset days");
if (array_key_exists($week, $events))
{
$events = (object) array(
'week' => $week_commencing->format('jS F Y'),
'events' => array()
);
}
$events->events[] = $event;
}
OK, so I've solved my issue now, with the following code:
public function index()
{
$events = Event::getEvents($perPage = 10);
$events_by_week = array();
foreach ($events as $event)
{
$start_date = DateTime::createFromFormat('Y-m-d', $event->start_date);
$week = $start_date->format('YW');
$monday = 1;
$day_offset = ($monday - $start_date->format('N'));
$week_commencing = $start_date->modify("$day_offset days");
if (!array_key_exists($week, $events_by_week))
{
$events_by_week[$week] = (object) array(
'week' => $week_commencing->format('jS F Y'),
'events' => array()
);
}
$events_by_week[$week]->events[] = $event;
}
$this->layout->content = View::make('events.index')->with(array('events_by_week' => $events_by_week, 'events' => $events));
}