Zend Framework Reg Ex not working on update form - regex

I have a client input form that has the following two reg expressions that works when creating a client but not when updating a client. The update form is a class that extends the crate form.
// Create text input for mobile
$mobile = new Zend_Form_Element_Text ('mobile');
$mobile->setLabel ('Mobile Number:')
->setDescription('Enter mobile in the format 353XXYYYYYYY')
->setOptions(array('size'=>'14'))
->setRequired(false)
->addValidator('Regex',false,array(
'pattern'=>'/^\d{12}$/',
'messages'=>array(
Zend_Validate_Regex::INVALID => '\'%value%\' Invalid mobile number it does not match the required format 353XXYYYYYYY',
Zend_Validate_Regex::NOT_MATCH =>'\'%value%\'does not match the required format 353XXXXXXXX')
)
)
->addFilter('HtmlEntities')
->addFilter('StringTrim');
// Create text input for landline
$landline = new Zend_Form_Element_Text ('landLine');
$landline->setLabel ('Phone Number:')
->setDescription('Enter phone number in the format +353(0) X YYY YYYZ')
->setOptions(array('size'=>'20'))
->setRequired(false)
->addValidator('StringLength', false, array('min' => 8))
->addValidator('Regex', false, array(
'pattern' => '/^\+353\(0\)\s\d\s\d{3}\s\d{3,4}$/',
'messages' => array(
Zend_Validate_Regex::INVALID =>
'\'%value%\' In valid Phone number does not match required number format +353(0) X YYY YYYZ',
Zend_Validate_Regex::NOT_MATCH =>
'\'%value%\' does not match required number format of +353(0) X YYY YYYZ'
)
))
->addFilter('HtmlEntities')
->addFilter('StringTrim');
When I enter an invalid mobile or land line number when creating a client the reg expression works and prevents the record from being saved.
However when I enter an invalid mobile or land line number when updating a client the reg expression fails and an 404 error occurs.
I think that the issue may be related to the get section of my update action within my controller as shown below but I can't figure out what is causing this as the route I have configured in my ini file retrieves the record as required.
public function updateAction(){
// generate input form
$form = new PetManager_Form_UpdateClient;
$this->view->form=$form;
/* if the requrest was made via post
test if the input is valid
retrieve current record
update values and save to DB */
if($form->isValid($this->getRequest()->getPost())){
$input=$form->getValues();
$client = Doctrine::getTable('PetManager_Model_Clients')
->find($input['clientid']);
$client->fromArray($input);
if($client->email=='')
{$client->email=NULL;}
if($client->mobile=='')
{$client->mobile=NULL;}
if($client->landLine=='')
{$client->landLine=NULL;}
if($client->address3=='')
{$client->address3=NULL;}
$client->save();
$sessionClient = new Zend_Session_Namespace('sessionClient');
$id = $client->clientid;
$fname = $client->firstName;
$lname = $client->lastName;
$sessionClient->clientid=$id;
$sessionClient->clientfName=$fname;
$sessionClient->clientlName=$lname;
$sessionClient->clientfName=$fname;
$this->_helper->getHelper('FlashMessenger')
->addMessage('The record for '.$fname.' '.$lname. ' was successfully updated.');
$this->_redirect('clients/client/success');
}else{
/* if GET request
set filters and validators for GET input
test if input is valid, retrieve requested
record and pree-populate the form */
$filters = array(
'id'=>array('HtmlEntities','StripTags','StringTrim')
);
$validators = array(
'id'=>array('NotEmpty','Int')
);
$input = new Zend_Filter_Input($filters,$validators);
$input->setData($this->getRequest()->getParams());
if($input->isValid()){
$qry = Doctrine_Query::create()
->from('PetManager_Model_Clients c')
->leftJoin('c.PetManager_Model_Counties co')
->where('c.clientid=?',$input->id);
$result = $qry->fetchArray();
if(count($result)==1){
$this->view->form->populate($result[0]);
}else{
throw new Zend_Controller_Action_Exception('Page not found',404);
}
}else{
throw new Zend_Controller_Action_Exception('Invalid Input');
}
}
}
All help greatly appreciated.

Ok I've sorted this I stupidly left out a check in my update action to see if the request was being made by post as this is the action defined in my form.
The corrected code is shown below in case this helps anyone else.
// action to update an individual clients details
public function updateAction()
{
// generate input form
$form = new PetManager_Form_UpdateClient;
$this->view->form=$form;
/* if the requrest was made via post
test if the input is valid
retrieve current record
update values and save to DB */
if ($this->getRequest()->isPost()) {
if($form->isValid($this->getRequest()->getPost())){
$input=$form->getValues();
$client = Doctrine::getTable('PetManager_Model_Clients')
->find($input['clientid']);
$client->fromArray($input);
if($client->email=='')
{$client->email=NULL;}
if($client->mobile=='')
{$client->mobile=NULL;}
if($client->landLine=='')
{$client->landLine=NULL;}
if($client->address3=='')
{$client->address3=NULL;}
$client->save();
$sessionClient = new Zend_Session_Namespace('sessionClient');
$id = $client->clientid;
$fname = $client->firstName;
$lname = $client->lastName;
$sessionClient->clientid=$id;
$sessionClient->clientfName=$fname;
$sessionClient->clientlName=$lname;
$sessionClient->clientfName=$fname;
$this->_helper->getHelper('FlashMessenger')
->addMessage('The record for '.$fname.' '.$lname. ' was successfully updated.');
$this->_redirect('clients/client/success');
}
}else{
/* if GET request
set filters and validators for GET input
test if input is valid, retrieve requested
record and pree-populate the form */
$filters = array(
'id'=>array('HtmlEntities','StripTags','StringTrim')
);
$validators = array(
'id'=>array('NotEmpty','Int')
);
$input = new Zend_Filter_Input($filters,$validators);
$input->setData($this->getRequest()->getParams());
if($input->isValid()){
$qry = Doctrine_Query::create()
->from('PetManager_Model_Clients c')
->leftJoin('c.PetManager_Model_Counties co')
->where('c.clientID=?',$input->id);
$result = $qry->fetchArray();
if(count($result)==1){
$this->view->form->populate($result[0]);
}else{
$t=count($result);
throw new Zend_Controller_Action_Exception('Page not found',404);
}
}else{
throw new Zend_Controller_Action_Exception('Invalid Input');
}
}
}

Related

Power Query connector - pagination issue

I am new to PQ and I want to get data from REST API.
The API uses pagination and in the 1st quary it returns two fileds. Table contains only 100 records.
IssueList = Table
NextBookmark = value
The url /issues?bookmark=[value] to get another page of issues.
I am trying to use https://learn.microsoft.com/en-us/power-query/samples/trippin/1-odata/readme tutorial to create connector but fails to get values from another page.
Code below:
Table.GenerateByPage = (getNextPage as function) as table =>
let
listOfPages = List.Generate(
() => getNextPage(null), // get the first page of data
(lastPage) => lastPage <> null, // stop when the function returns null
(lastPage) => getNextPage(lastPage) // pass the previous page to the next function call
),
// concatenate the pages together
tableOfPages = Table.FromList(listOfPages, Splitter.SplitByNothing(), {"Column1"}),
firstRow = tableOfPages{0}?
in
// if we didn't get back any pages of data, return an empty table
// otherwise set the table type based on the columns of the first page
if (firstRow = null) then
Table.FromRows({})
else
Value.ReplaceType(
Table.ExpandTableColumn(tableOfPages, "Column1", Table.ColumnNames(firstRow[Column1])),
Value.Type(firstRow[Column1])
);
GetAllPagesByNextLink = (url as text) as table =>
Table.GenerateByPage((previous) =>
let
// if previous is null, then this is our first page of data
nextLink = if (previous = null) then url else Value.Metadata(previous)[NextLink]?,
// if NextLink was set to null by the previous call, we know we have no more data
page = if (nextLink <> null) then GetPage(nextLink) else null
in
page
);
GetPage = (url as text) as table =>
let
response = Web.Contents(url, [ Headers = DefaultRequestHeaders ]),
body = Json.Document(response),
nextLink = GetNextLink(body),
data = Table.FromRecords(body[IssueList])
in
data meta [NextLink = nextLink];
GetNextLink = (response) as nullable text => Record.FieldOrDefault(response[NextBookmark], "NextBookmark");
PQ.Feed = (url as text) as table => GetAllPagesByNextLink(url);
Can anyone help me out?
Thanks in advance for words of advice :)

create customer payment profile in authorize.net

I am facing a very strange behavior in using the API to create the customer profiles. Although i have read the documentation thoroughly but did not succeed.
I am creating a customer profile at first when no profile is available along with a payment profile but next time when a user return and add the payment profile ( as the customer profile already exist) i am using only createCustomerPaymentProfile. The thing is, in first step i am not including $billto->setZip("44628"); and it goes well. But when i make only payment Profile it demands me to include the zip code too other wise it gives error
"There is one or more missing or invalid required fields."
I am using the exact same code which is in the php section of the documentation just a change in text/parameters.
create customer profile
create customer payment profile
For making the customer profile :
private function createCustomerProfile($data)
{
/* Create a merchantAuthenticationType object with authentication details
retrieved from the constants file */
$merchantAuthentication = new AnetAPI\MerchantAuthenticationType();
$merchantAuthentication->setName("auth");
$merchantAuthentication->setTransactionKey("transkey");
// Set the transaction's refId
$refId = 'ref' . time();
$paymentProfile=$this->newPaymentProfile($data);
// Create a new CustomerProfileType and add the payment profile object
$customerProfile = new AnetAPI\CustomerProfileType();
$customerProfile->setDescription("Customer 2 Test PHP");
$customerProfile->setMerchantCustomerId($name. time());
$customerProfile->setEmail($email);
$customerProfile->setpaymentProfiles($paymentProfile);
// Assemble the complete transaction request
$request = new AnetAPI\CreateCustomerProfileRequest();
$request->setMerchantAuthentication($merchantAuthentication);
$request->setRefId($refId);
$request->setProfile($customerProfile);
// Create the controller and get the response
$controller = new AnetController\CreateCustomerProfileController($request);
$response = $controller->executeWithApiResponse(\net\authorize\api\constants\ANetEnvironment::SANDBOX);
if (($response != null) && ($response->getMessages()->getResultCode() == "Ok")) {
$paymentProfiles = $response->getCustomerPaymentProfileIdList();
//Insert into database for the profile and payment profile update
} else {
echo "ERROR : Invalid response\n";
$errorMessages = $response->getMessages()->getMessage();
echo "Response : " . $errorMessages[0]->getCode() . " " .$errorMessages[0]->getText() . "\n";
}
return $response;
For making the customer payment profile
private function createCustomerPaymentProfile($data){
/* Create a merchantAuthenticationType object with authentication details
retrieved from the constants file */
$merchantAuthentication = new AnetAPI\MerchantAuthenticationType();
$merchantAuthentication->setName("name");
$merchantAuthentication->setTransactionKey("transkey");
// Set the transaction's refId
$refId = 'ref' . time();
$paymentProfile=$this->newPaymentProfile($data);
// Assemble the complete transaction request
$paymentprofilerequest = new AnetAPI\CreateCustomerPaymentProfileRequest();
$paymentprofilerequest->setMerchantAuthentication($merchantAuthentication);
// Add an existing profile id to the request
$paymentprofilerequest->setCustomerProfileId($data['profile_id']);
$paymentprofilerequest->setPaymentProfile($paymentProfile[0]);
$paymentprofilerequest->setValidationMode("liveMode");
// Create the controller and get the response
$controller = new AnetController\CreateCustomerPaymentProfileController($paymentprofilerequest);
$response = $controller->executeWithApiResponse(\net\authorize\api\constants\ANetEnvironment::SANDBOX);
if (($response != null) && ($response->getMessages()->getResultCode() == "Ok") ) {
echo "Create Customer Payment Profile SUCCESS: " . $response->getCustomerPaymentProfileId() . "\n";
//Insert into database for the profile and payment profile update
} else {
echo "Create Customer Payment Profile: ERROR Invalid response\n";
$errorMessages = $response->getMessages()->getMessage();
echo "Response : " . $errorMessages[0]->getCode() . " " .$errorMessages[0]->getText() . "\n";
}
return $response;
}
for the re-usability purpose i have make a common make payment profile which return the payment profile array
private function newPaymentProfile($data){
// Set credit card information for payment profile
$creditCard = new AnetAPI\CreditCardType();
$creditCard->setCardNumber($data['account_number']);
$creditCard->setExpirationDate($data['date']);
$creditCard->setCardCode($data['securiy_no']);
$paymentCreditCard = new AnetAPI\PaymentType();
$paymentCreditCard->setCreditCard($creditCard);
// Create the Bill To info for new payment type
$billTo = new AnetAPI\CustomerAddressType();
$billTo->setFirstName($data['holder_name']);
$billTo->setAddress($data['billing_address']);
$billTo->setPhoneNumber($data['phone']);
$billTo->setfaxNumber($data['fax']);
// Create a new CustomerPaymentProfile object
$paymentProfile = new AnetAPI\CustomerPaymentProfileType();
$paymentProfile->setCustomerType('individual');
$paymentProfile->setBillTo($billTo);
$paymentProfile->setPayment($paymentCreditCard);
$paymentProfiles[]=$paymentProfile;
return $paymentProfiles;
}

Update and Save a record programmatically in vTiger

Currently I'm trying to change the 'Assigned To' user for a lead to the current user whenever a user enters the lead details screen.
I have the following code:
function checkPermission(Vtiger_Request $request) {
$moduleName = $request->getModule();
$recordId = $request->get('record');
$recordModel = Vtiger_Record_Model::getInstanceById($recordId, $moduleName);
$recordModel->set('assigned_user_id',$current_user->id);
$recordModel->save();
...
return true;
}
The problem is, instead of saving the current record with a new assigned user, vTiger duplicates this record into a new record and saves it with the current user as a new assigned user.
Working on vTiger v6.2.0
You need to set mode is edit to recordModel before save
$recordModel->set('mode','edit');
Try something like this:
$recordModel= Vtiger_Record_Model::getInstanceById($recordId,$moduleName);
$recordModel->set(my_fields, my_new_value);
$recordModel->set(my_fields2, my_new_value2);
$recordModel->set('mode', 'edit');
$recordModel->save();
Tray with event Handler;
create a file: /modules/yourmodulename/handlers/RecordUpdater.php
then put the code below in your file RecordUpdater.php :
require_once 'include/events/VTEventHandler.inc';
class yourmodulename_RecordUpdater_Handler extends VTEventHandler {
function handleEvent($eventName, $data) {
global $adb;
$currentUserModel = Users_Record_Model::getCurrentUserModel();
$module = $data->getModuleName();
if ($eventName === 'vtiger.entity.beforesave' AND $module === "yourmodulename") {
require_once 'modules/yourmodulename/yourmodulename.php';
$currentUserId = $currentUserModel->getId();
$data->set('assigned_user_id', $currentUserId);
}
}
}
finally don't forget to insert in vtiger_eventhandlers table:
INSERT INTO `vtigercrm`.`vtiger_eventhandlers` (
`eventhandler_id` ,
`event_name` ,
`handler_path` ,
`handler_class` ,
`cond` ,
`is_active` ,
`dependent_on`
)
VALUES (
NULL , 'vtiger.entity.beforesave', 'modules/yourmodulename/handlers/RecordUpdater.php', 'yourmodulename_RecordUpdater_Handler', NULL , '1', '[]'
);
then increment vtiger_eventhandlers_seq with 1
that's it :)
I hope, that helps you

VirtueMart 2.6.6 custom field (cart variable) not displayed in the order details

I programmed a custom field plugin for Virtuemart 2.6.6, which show some parameters on the product page for example "size", and that parameter is a cart variable either.
A huge help was this article:
https://www.spiralscripts.co.uk/Joomla-Tips/custom-plugin-fields-in-virtuemart-2-2.html
And of course stackoverflow forum and factory default VM custom plugins.
Everything is working (the size is displayed in product details view, and in the cart, when you added the product to it) but one thing:
after sending the order the parameter has not displayed in the order details, so I don't know what size of product was bought.
I placed following functions into my plugin, but not solved my problem:
function plgVmOnViewCart($product, $row, &$html)
{
if (empty($product->productCustom->custom_element) or $product->productCustom->custom_element != $this->_name) return '';
if (!$plgParam = $this->GetPluginInCart($product)) return false ;
$html .= '<div class="parameterek_attributes">';
foreach ($plgParam as $attributes) {
foreach ($attributes as $k => $attribute) {
if ($k =='child_id') continue;
if ($k == 'custom_param_default3') $name = 'Veľkosť'; else $name = '';
$html .='<span class="parameterek_attribute"> '.$name.': '.JText::_($attribute).' </span>';
}
}
$html.='</div>';
return true;
}
/**
*
* shopper order display BackEnd
*/
function plgVmDisplayInOrderBE($item, $row,&$html)
{
if (empty($item->productCustom->custom_element) or $item->productCustom->custom_element != $this->_name) return '';
if(!empty($productCustom)){
$item->productCustom = $productCustom;
}
$this->plgVmOnViewCart($item, $row,$html);
}
/**
*
* shopper order display FrontEnd
*/
function plgVmDisplayInOrderFE($item, $row,&$html)
{
if (empty($item->productCustom->custom_element) or $item->productCustom->custom_element != $this->_name) return '';
$this->plgVmOnViewCart($item, $row,$html);
}
Into database table called #__virtuemart_order_items were saved values: something like:
{"357":"5"}
but it should be something like:
{"357":"size M"}
I see that the key function is GetPluginInCart($product), and when I printed out the $product->param in that function I've got this output, when I go through checkout process:
Array
(
[0] => Array
(
[parameterek] => Array
(
[custom_param_default3] => L
)
)
)
but after I finish the order and go into order details the $product->param has this value:
Array
(
[357] => 5
)
So I think, before I finish the order I have to somehow handle the
chosen product parameter and transform it into the correct form, but
I don't know how.
On the following site
https://dev.virtuemart.net/projects/virtuemart/wiki/Product_Plugins
I found a function:
plgVmOnViewCartOrder($product, $param,$productCustom, $row)
handel $param before adding it in the order
return $param;
but when I searched for the string "plgVmOnViewCartOrder" in the whole virtuemart installation, it was not found, so it means it is not launched (?)
If anybody could help me or send a fair documentation would be very good. Thank you!
I think, I solved my problem, what was:
in function plgVmOnDisplayProductVariantFE I made a mistake, I didn't use layout renderer, which generates an object $viewData with variable virtuemart_customfield_id.
Then in your plugin's layout, input field name has to be as follows:
<input
class="parameterekInput"
type="radio"
id="plugin_param['.$viewData[0]->virtuemart_customfield_id.']['.$this->_name.']['.$c.']"
name="customPlugin['.$viewData[0]->virtuemart_customfield_id.']['.$this->_name.'][custom_param_default3]"
value="'.$size.'" />
so the name attribute should be always:
customPlugin['.$viewData[0]->virtuemart_customfield_id.']['.$this->_name.'][whatever]
The right usage of plgVmOnDisplayProductVariantFE function is to use expression:
$group->display .= $this->renderByLayout('default',array($field,&$idx,&$group )
Here the whole function with the right expresion:
function plgVmOnDisplayProductVariantFE ($field, &$idx, &$group) {
if ($field->custom_element != $this->_name) return '';
$this->getCustomParams($field);
$this->getPluginCustomData($field, $field->virtuemart_product_id);
$group->display .= $this->renderByLayout('default',array($field,&$idx,&$group ) );
return true;
}
Now when I print_r -ing $product->param in function GetPluginInCart($product), I get this:
Array
(
[273] => Array //previously the key was Zero, now it is 273, value of virtuemart_customfield_id
(
[parameterek] => Array
(
[custom_param_default3] => L
)
)
)
...and now I'm glad, that I can move on in my project :)

What is the preferred method of updating Money fields in Dynamics CRM 2013 via Web Services?

I have an entity in CRM that has some Money fields on them. At the time of the creation of the entity there is no value for those fields, so the entity is created and saved. However if I then have values and go to update them (either through the UI or Web Services) I basically get an error stating "The currency cannot be null".
In the UI:
I then get a red circle with an X through it if I go to update the value.
In the code (web service call):
var crmService = new CrmServiceReference.IFAAContext(new Uri(crmWebServicesUrl));
crmService.Credentials = System.Net.CredentialCache.DefaultCredentials;
var crmAccount = crmService.AccountSet.Where(a => a.AccountId == accountId).FirstOrDefault();
crmAccount.myitems_MoneyValueItem.Value = 10.0m;
crmService.UpdateObject(crmAccount);
crmService.SaveChanges()
I then get the "The currency cannot be null" on the .SaveChanges() call.
In the code (second attempt):
var crmService = new CrmServiceReference.IFAAContext(new Uri(crmWebServicesUrl));
crmService.Credentials = System.Net.CredentialCache.DefaultCredentials;
var crmAccount = crmService.AccountSet.Where(a => a.AccountId == accountId).FirstOrDefault();
var crmCurrency = crmService.TransactionCurrencySet.Where(c => c.ISOCurrencyCode == "AUD").First();
crmService.SetLink(crmAccount, "TransactionCurrency_Account", crmCurrency);
//crmService.SaveChanges() /* tried with this uncommented as well to try and "set currency" before setting value */
crmAccount.myitems_MoneyValueItem.Value = 10.0m;
crmService.UpdateObject(crmAccount);
crmService.SaveChanges()
So this attempt fails in the same way, however if I run it a second time (without the currency and SetLink) so that the currency was saved before then it does work - hence the atempt to do a second .SaveChanges() but really need it to sort of work the first time through.
In the code (third attempt):
var crmService = new CrmServiceReference.IFAAContext(new Uri(crmWebServicesUrl));
crmService.Credentials = System.Net.CredentialCache.DefaultCredentials;
var crmAccount = crmService.AccountSet.Where(a => a.AccountId == accountId).FirstOrDefault();
crmAccount.athos_MoneyValueItem= new CrmServiceReference.Money() { Value = 10.0m };
crmService.UpdateObject(crmAccount);
crmService.SaveChanges()
This doesn't appear to work either
When you create a new record containing a Money field (or updating an existing one where no Money fields are filled before) , you need to specify the currency, the right field to set is TransactionCurrencyId (logical name transactioncurrencyid), it's a lookup (so inside the code is an EntityReference) to the currency entity.
assuming you have the Guid of your currency stored inside the currencyId variable:
var crmAccount = crmService.AccountSet.Where(a => a.AccountId == accountId).FirstOrDefault();
crmAccount.TransactionCurrencyId = new EntityReference(TransactionCurrency.LogicalName, currencyId);
crmAccount.myitems_MoneyValueItem = new Money(10.0m); //better to update the money field with this syntax
crmService.UpdateObject(crmAccount);
crmService.SaveChanges()
CRM 2013 expects a Money object for a currency field.
crmAccount.myitems_MoneyValueItem = new Money(10.0m);
You shouldn't have to explicitly declare a currency unless your CRM organization doesn't have a default currency set (and since you need to set this when creating an organization, it should always be set).
It looks like if I do a lookup on currency (shame as an extra data call) and then use that to set the TransactionCurrencyId it then "works" ... seems like I shouldn't have to do this as I do have a default set for the organisation though. But this does appear to be working in that it results in being able to update those fields.
var crmCurrency = crmService.TransactionCurrencySet.Where(c => c.ISOCurrencyCode == currencyCode).First();
var crmService = new CrmServiceReference.IFAAContext(new Uri(crmWebServicesUrl));
crmService.Credentials = System.Net.CredentialCache.DefaultCredentials;
var crmAccount = crmService.AccountSet.Where(a => a.AccountId == accountId).FirstOrDefault();
crmAccount.TransactionCurrencyId = new CrmServiceReference.EntityReference() { Id = crmCurrency.TransactionCurrencyId, LogicalName = "transactioncurrency", Name = crmCurrency.CurrencyName };
crmAccount.myitems_MoneyValueItem.Value = 10.0m;
crmService.UpdateObject(crmAccount);
crmService.SaveChanges();
i am doing the same thing as you but unable to set the money field value during service.create.
I have already put in
entity.Attributes["transactioncurrencyid"] = currencyGuid;
entity.Attributes["new_moneyfield"] = new Money(123.45M);
but in the end, the record is created with the transactioncurrency field populated, while the money field is blank.
Its a custom workflow on CRM online 2016 by the way..