I have a case where I have to clone a record in controller, modify the cloned and original records slightly and then save them both. I have tried implemeting in many different ways but always end up with one recod not being updated or being update wrong. Here is the code that gets me closest:
public function postpone( $id = null ){
$this->request->allowMethod( ['post'] );
$originalTask = $this->Tasks->get( $id );
//information that has to be updated
$meetingId = 200;
//set original to removed and update it
$originalTask->removed = 1;
if( $this->Tasks->save( $originalTask ) ){
//Logic for storing a clone task
$cloneTask = $originalTask;
$cloneTask->id = NULL;
$cloneTask->removed = 0;
$cloneTask->meeting_id = $meetingId;
$this->Tasks->save( $cloneTask );
}
}
What happens in this case is that when storing $cloneTask simply $originalTask is being updated and that is it, where instead a need to get a new record.
I have no custom before or after save logic that could influence it.
You should create a new entity before you can save a "cloneTask".
if( $this->Tasks->save( $originalTask ) ){
//Logic for storing a clone task
$cloneTask = $this->Tasks->newEntity();
$cloneTask->removed = 0;
$cloneTask->meeting_id = $meetingId;
$this->Tasks->save( $cloneTask );
}
Related
I want to insert the below default values when i am running the service i got this below error any one please tell me how to resolve.
Runtime error in script ("Process: 'CustomPersonalGS Practice' ProcessItem: 'Initialize' Type: 'ITEM'" -1:-1).TypeError: Cannot read property "parameters" from null
//Initialise SQL Query List
tw.local.sqlQueries = new tw.object.listOf.SQLStatement();
tw.local.sql = "";
tw.local.customerPD = new tw.object.customerPD1BO();
tw.local.customerPD.customerPersonalDetailsList = new tw.object.listOf.customerSpecificPersonalDetailsListBO();
var custPersonalDetails = new tw.object.customerSpecificPersonalDetailsListBO();
custPersonalDetails.customerId = "8467";
custPersonalDetails.custPersonalDetailsId = "8";
custPersonalDetails.isBPMEnabled = true;
custPersonalDetails.isCCPEnabled = true;
custPersonalDetails.isCCPMandatory = true;
custPersonalDetails.isLatestVersion = true
tw.local.customerPD.customerPersonalDetailsList.insertIntoList(tw.local.customerPD.customerPersonalDetailsList.listLength, custPersonalDetails);
tw.local.sql = "INSERT INTO CUSTOMPERSONALDETAILSQUESTION(CUSTOMERID,CUSTPERSONLADETAILSID,ISBPMENABLED,ISCCPENABLED,ISCCPMANDATORY,ISLATESTVERSION) VALUES (?,?,?,?,?,?) ";
function addSQLStatement() {
tw.local.sqlQueries[tw.local.sqlQueries.listLength] = new tw.object.SQLStatement();
}
function addParam(value,type,mode) {
log.info("VALUE :" + value);
var newParam = new tw.object.SQLParameter();
newParam.value = value;
newParam.type = type;
newParam.mode = mode;
if( tw.local.sqlQueries == null){
tw.local.sqlQueries = new tw.object.listOf.SQLStatement();
}
if( tw.local.sqlQueries[tw.local.sqlQueries.listLength] == null ){
tw.local.sqlQueries.insertIntoList(tw.local.sqlQueries.listLength, new tw.object.SQLStatement());
}
if(tw.local.sqlQueries[tw.local.sqlQueries.listLength].parameters == null ){
tw.local.sqlQueries[tw.local.sqlQueries.listLength].parameters = new tw.object.listOf.SQLParameter();
}
var paramsLength = tw.local.sqlQueries[tw.local.sqlQueries.listLength].parameters.listLength;
tw.local.sqlQueries[tw.local.sqlQueries.listLength].parameters[paramsLength] = newParam;
}
for(var i=0;i<tw.local.customerPD.customerPersonalDetailsList.listLength;i++){
addSQLStatement(tw.local.sql);
addParam(tw.local.customerPD.customerPersonalDetailsList[i].customerId,"VARCHAR","IN");
addParam(tw.local.customerPD.customerPersonalDetailsList[i].custPersonalDetailsId,"VARCHAR","IN");
var yesNoFlag = "N";
if(tw.local.customerPD.customerPersonalDetailsList[i].isBPMEnabled){
yesNoFlag="Y";
addParam(yesNoFlag,"CHAR","IN");
}
yesNoFlag = "N";
if(tw.local.customerPD.customerPersonalDetailsList[i].isCCPEnabled){
yesNoFlag="Y";
addParam(yesNoFlag,"CHAR","IN");
}
yesNoFlag = "N";
if(tw.local.customerPD.customerPersonalDetailsList[i].isCCPMandatory){
yesNoFlag="Y";
addParam(yesNoFlag,"CHAR","IN");
}
yesNoFlag = "N";
if(tw.local.customerPD.customerPersonalDetailsList[i].isLatestVersion){
yesNoFlag="Y";
addParam(yesNoFlag,"CHAR","IN");
}
}
You didn't initialize the parameter list in your SQL as far as I can tell. That is on line 38 you call -
var paramsLength = tw.local.sqlQueries[tw.local.sqlQueries.listLength].parameters.listLength;
However when you create the entry in the tw.local.sqlQueries, you didn't initialize the parameter array. I'll also note that your addSQLStatement() function ignore the sql input (and that value is hard coded, so really you don't need to pass it in). I think if you change addSQLStatement to be something like -
function addSQLStatement(query) {
var targetQuery = new tw.object.SQLStatement();
targetQuery.sql = query;
tagetQuery.params = new tw.object.listOf.SQLParameter();
tw.local.sqlQueries[tw.local.sqlQueries.listLength] = targetQuery;
}
then your code will work. Additionally you could actually return targetQuery from this function and then pass it to the "addParams" method eliminating the need to find the last one in the array. Alternatively insert it in the beginning of the array instead and just update the 0th item instead of the last.
-AP
This comparison will never work properly. array[array.length] will always be null (line 35).
if (tw.local.sqlQueries[tw.local.sqlQueries.listLength].parameters == null ){
In addition, in the next lines, if you want to work with the last element of the list, you might want to use something like array[array.length - 1]. Personally, I'd use some temporary variable, do some stuff with it and insert it into the list at the end (similar to #Drux's answer).
I am using angluar js. On my page I have a table. Each record in the table has a col that is a drop down list. When this value gets changed and the user clicks save, the page checks to see if the value in the drop down has already been used. If it has, an alert message is presented and if not, then some code is executed. My problem is when the alert/error message is displayed. When this is displayed, I don't want the table to update according to the new value but it still does. How can I prevent this? I am really new to using angular.
$scope.saveDeviceUpdate = function (updatedDevice, deviceId) {
var numDevicesForBus = 0;
for (var i = 0; i < $scope.data.deviceList.length; i++)
{
if ($scope.data.deviceList[i].BusNumber == updatedDevice.busNumber)
{
numDevicesForBus++;
}
}
if (numDevicesForBus == 0)
{
dataService.updateDevice(updatedDevice, deviceId);
}
else
{
alert("This bus already has a device!");
}
};
I'm using ObjectEvents to give ActivityPoints to current user based on fields user filled.
Now for example if user register and fill FirstName I will give 10 points to user.
The problem is that I'm handling ObjectEvents.Update.After and inside it I'm updating userSettings.This causes a unlimited loop and application stops working.
is there any work around?
this is the code block:
var className = e.Object.TypeInfo.ObjectClassName;
DataClassInfo dci = DataClassInfoProvider.GetDataClass(className);
if (dci != null)
{
var fi = new FormInfo(dci.ClassFormDefinition);
if (fi != null)
{
var stopProccess = true;
var fields = new List<FormFieldInfo>();
foreach (var changedColumn in e.Object.ChangedColumns())
{
var field = fi.GetFormField(changedColumn);
var activityPointMacro = ValidationHelper.GetString(field.Settings["ActivityPointMacro"], "");
if (!string.IsNullOrEmpty(activityPointMacro))
{
fields.Add(field);
stopProccess = false;
}
}
if (!stopProccess)
{
var contextResolver = CMSContext.CurrentResolver.CreateContextChild();
foreach (FormCategoryInfo info in fi.ItemsList.OfType<FormCategoryInfo>())
{
contextResolver.SetNamedSourceData(info.CategoryName, info);
}
EditingFormControl data = new EditingFormControl();
foreach (FormFieldInfo info2 in fi.ItemsList.OfType<FormFieldInfo>())
{
contextResolver.SetNamedSourceData(info2.Name, data);
}
foreach (var field in fields)
{
{
var activityPointMacro = ValidationHelper.GetString(field.Settings["ActivityPointMacro"], "");
var activityPoint =
ValidationHelper.GetInteger(contextResolver.ResolveMacros(activityPointMacro), 0);
CMSContext.CurrentUser.UserSettings.UserActivityPoints += activityPoint;
CMSContext.CurrentUser.UserSettings.Update();
}
}
}
}
}
If you just need to give points for user fields then you could just use ObjectEvents.Update.Before, check fields are not empty and assign points. But i can see from the code, you want to have something more complex bulit over macro expressions. So I have a few suggestions for you.
1) ObjectEvents.Update.Before instead of ObjectEvents.Update.After still may be a good idea. Ideally you set your additional values and all is set during one update.
2) Watch only the class names you need
3) Always prefer Provider.SetInfo methods over info.Update(). In case of user settings it's best to set whole user info, so UserInfoProvider.SetUserInfo. Provider methods may add some additional important logic.
4) The code seems like it'll add the points with every update of a user
5) if you are still running into a loop, you need to flag somehow, that some part of code should not be executed again. The best way is to use RequestStockHelper class - add a bool value with a specificname like "PointsProcessed".
I am working on a code for a quiz test, here
function run($id){
//Is this the first question ?
if($this->data){
$question_no = $this->Session->read('Test.qno'); //0
$last_answer = $this->Session->read('Test.last_answer');
$question_no = $question_no + 1; //1
$this->Session->write('Test.qno',$question_no); //Test.qno = 1
$this->Session->setFlash('last_answer'.$this->data['Test']['answer']);
$this->redirect($this->referer());
if($this->data['Test']['answer']==$last_answer){
$score = $this->Session->read('Test.score');
$score = $score + 1 ;
$this->Session->write('Test.score',$score);
$this->Session->setFlash('Correct answer');
}
}
$question_no = $this->Session->read('Test.qno'); //question_no =
if(!$question_no){
$question_no = 0;
$this->Session->write('Test.qno',$question_no);
$this->Session->write('Test.score',0);
}
$question = $this->Test->Question->find('first',array('conditions'=>array('Question.test_id ='=>$id),'offset'=>$question_no));
$answer = $question['Question']['answer'];
$this->Session->write('Test.last_answer',$answer);
if(empty($question)){
$score = $this->Session->read('Test.score');
$this->Session->setFlash('Your Score is '.$score);
$this->Session->write('Test.qno',0);
$this->redirect(array('controller'=>'States','action'=>'index'));
}
else{
$this->set(compact('question'));
}
}
here data comparison fails even though they both hold the same value can some one tell me why,here $last_answer is retrieved from session and holds a number.
$this->data['Test']['answer'] is taken from a form with radio button's
Add
debug( '"'.$this->data['Test']['answer'].'"' );
debug( '"'.$last_answer.'"' );
to confirm they really are the same.
Also make sure it's not a problem with sessions (i.e. the condition is true, but the code inside doesn't do anything): add debug( "true" ); inside the if block and confirm that you see the message.
UPDATE after seeing the whole code:
You have a $this->redirect() right before the if block! Of course the code you initially posted doesn't do anything because you redirect the user to another page before the execution even reaches it.
I have an array of objects, each of which is assigned an ID when it is first created. I give the user the ability to visually reorder the objects, which changes their position in the array. They then have the option to save that order using a flash sharedObject or "cookie" and then later, if they reopen the flash file, I want them to be able to hit a button to restore that order. I'm just not sure what the syntax would be to set the object's index within the array. Here's my code:
VARIABLES:
var project_settings = SharedObject.getLocal("settings"); //saves all project settings for the next time the file is opened
var project_order:Array = []; //saves project order for the next time the file is opened
var project_display:Array = []; //saves whether each project should be displayed or hidden for the next time the file is opened
SAVE CODE:
function saveOrder(){
for (var i=0;i<project_array.length;i++){
project_order[i] = project_array[i].id;
project_display[i] = project_array[i].projectThumb.thumbActive;
}
project_settings.data.order = project_order;
project_settings.data.active = project_display;
//trace (project_settings.data.active[1]);
project_settings.flush(); //saves most recent "cookie"
}
RESTORE CODE:
function loadOrder(){
for (var i=0;i<project_array.length;i++){
/* NEED THE CODE THAT GOES HERE. BASICALLY, PROJECT_ARRAY[i] SHOULD BE THE ITEM WITH AN ID EQUAL TO PROJECT_SETTINGS.DATA.ORDER[i] */
}
}
Something like this should work:
function loadOrder()
{
var dict = new Dictionary();
for (var i = 0; i < project_array.length; i++)
dict[project_array[i].id] = project_array[i];
project_array = [];
for (var i = 0; i < project_settings.data.order.length; i++)
project_array[i] = dict[project_settings.data.order[i]];
}
Just load in your array and sort on the ID. Something like this should work:
private function _loadArray():void
{
// fill in your array
project_array.sort( this._sortFunc );
}
// replace the * by whatever your object type is
private function _sortFunc( a:*, b:* ):int
{
return a.id - b.id;
}
More info: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/Array.html#sort()
Or even the sortOn() function (which might be easier) should work:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/Array.html#sortOn()