Can I use same param name multiple times in the URL for codeigniter-restserver? - codeigniter-restserver

http://example.com/api/transfer/transfers/code/456/code/234
When using $this->get('code') on a url like above I expect the REST library to return an array or a list of the codes.
Instead it returns the last one.
Is there a way to return both values in a list, or is there another recommandation for formating the URL.
Thank you

I know it has been long since you posted the question. However it could help other people looking for the same thing.
Assuming that transfer is your controller and transfers is the function, another way to format your url could be:
http://example.com/api/transfer/transfers?code[]=456&code[]=234
This was you perform $this->get('code') you'll get an array back.
If you are creating the url via code then you may use http_build_query(). It handles the necessary escaping. It means it will replace [ for %5B and ] for %5D, in this case.
The code would be like:
$codes = array(456, 234);
$query = http_build_query(array('code' => $data));
$url = 'http://example.com/api/transfer/transfers?' . $query;

Related

I'm try to use toLowerCase() along with .replace() method for a use case but having some difficulty

Let's say I have a website url named:
https://clients.website.com/mock-client/matrix
or
https://clients.website.com/mock-client/Matrix
I'm trying to write some AngularJS code that will take the raw url as shown as an example above and remove the /matrix portion only. The thing is...is that it could be /matrix or /Matrix.
My current code looks like this:
var clientNetworkUrl =
https://clients.website.com/mock-client/matrix
or
https://clients.website.com/mock-client/Matrix
vm.click = function() {
var learnMoreUrl = clientNetworkUrl.replace('matrix', '');
$window.open(learnMoreUrl, '_blank');
};
I would like the output of the function to always strip out /matrix whether it's capitalized or not.
I tried lowercasing the whole url and read that might be a bad idea so I want to take a different approach.
Can anyone help me out with this?
Just use a case sensitive regex
var urls =['https://clients.website.com/mock-client/matrix',
'https://clients.website.com/mock-client/Matrix']
urls.forEach(str => console.log(str.replace(/matrix/gi,'')))

How do I bulk/chunk paginate existing Seq[(String)] session value in Gatling?

I am executing a call that saves a lot of values into a Seq[(String)], it looks as follows:
.exec(session => {session.set("Ids", session("externalIds").as[Seq[String]])})
There is a reason why I have to create another session variable called Ids our of externalIds but I wont get into it now.
I than have to execute another call and paginate 10 values out of ${Ids} until I send them all.
(So in case of 100 values, I'll have to execute this call 10 times)
The JSON looks as follows:
..."Ids": [
"962950",
"962955",
"962959",
"962966",
"962971",
"962974",
"962978",
"962983",
"962988",
"962991"
],...
What I usually do when I have to iterate through one value each time is simply:
.foreach("${Ids}", "id") {
exec(getSomething)
}
But since I need to send a [...] Of 10 values each, I am not sure if it should even be in the scenario level. Help! :)
Use transform in your check to transform your Seq[String] into chunks, eg with Seq#grouped.
I couldn't figure out how to go about this within the session so I took it
outside to a function and here is the solution:
.exec(session => {session.set("idSeqList", convertFileIdSeqToFileIdSeqList(session("idsSeq").as[Seq[String]]))})
def convertFileIdSeqToFileIdSeqList(idSeq: Seq[String]): Seq[Seq[String]] = {
idSeq.grouped(10).toList
}
Note that when placing your list within a JSON body, you will need to use .jsonStringify() to format it correctly in the JSON context like so:
"ids": ${ids.jsonStringify()},

can't manipulate JSON obtained through multiple $http.get and $q

I am trying to merge two jsons into one but can't make it work. I manage to retrieve the data I need from both get, but I have troubles manipulating the jsons.
I planned on using two for loops but it doesn't work :
$scope.coursesJson = $http.get('https://api.myjson.com/bins/18zi3');
$scope.reviewsJson = $http.get('https://api.myjson.com/bins/52toz');
$q.all([$scope.coursesJson, $scope.reviewsJson]).then(function (values){
$scope.coursesJson = values[0];
$scope.reviewsJson = values[1];
for(i = 0;i<$scope.coursesJson.length;i++){
for(j = 0;j<$scope.reviewsJson.length;j++){
if($scope.coursesJson[i].name = $scope.reviewsJson[j].name){
$scope.coursesJson[i].reviews.push($scope.reviewsJson[j]);
}
}
}
console.log($scope.coursesJson);
});
Using the console, I can visualise the data but $scope.coursesJson.length is undefined and I don't understand why.
Maybe I don't understand $q well ?
EDIT :
Here is an example of the elements you could find in the coursesJson file I get() :
[{"code":"123 ","name":"Acteurs","courseContentGrade":null,"courseTeachingGrade":null,"courseAverage":null,"reviews":null},
{"code":"1234","name":"Advanced Excel","courseContentGrade":null,"courseTeachingGrade":null,"courseAverage":null,"reviews":null}]
And an example of the elements you could find in the reviewsJson file I get() :
[{"code":"123 ","name":"Acteurs","professor":"Lalala","contentReview":"C'est très réussi.","teachingReview":"charismatique","contentGrade":8,"teachingGrade":8,"average":8,"trimester":"T2","day":"Jeudi / Thursday","time":"9h-12h","round":"1er tour","bet":21,"year":"2014/2015","upvotes":"0","author":"Piranha","passed":null},
{"code":"123 ","name":"Acteurs","professor":"LAlalalala","contentReview":"Très intéressant !","teachingReview":"Disponible, claire.","contentGrade":8,"teachingGrade":8,"average":8,"trimester":"T2","day":"Jeudi / Thursday","time":"9h-12h","round":"1er tour","bet":25,"year":"2014/2015","upvotes":"0","author":"Piranha","passed":null}]
I would like to add the elements found in the reviewsJson to the reviews field of the elements of coursesJson. Could that be the problem ? I thought that using the push() method would create the array, but maybe I need to change all "reviews":null to "reviews":[] in coursesJson ?
I went to the url https://api.myjson.com/bins/ID1 and it's not an array, but an object. Instead of $scope.coursesJson.length I think you shouldbe doing $scope.coursesJson.tracks.length
I solved my issue really easyly and my question was actually pretty stupid.
What I tried to achieve didn't have its place on the front but on the backend.

CakePHP Router: how to pass the first parameter null?

My action is defined like this:
function actionName($par1 = null, $par2 = null)
I need a special route looking like: example.com/r/ABCD which should call
SomeController->actionName(null, "ABCD")
How is it to achieve with Cake's Router::connect() ?
You can try reversing the params like
function actionName( $par2 = null, $par1 = null)
1.- arg1 optional, arg2 not optional
I would change the order of the parameters, so the first parameter is truly optional.
2.- arg1 optional, arg2 not optional, without reordering
(not the best idea, but I assumed business rules required it)
Make a wrapper function.
SomeController {
wrapperFun(arg2) {
actualFunction(null, arg2)
}
actualFun(arg1, arg2) {
// do something
}
}
Now you can have:
SomeController/wrapperFun/ABC
SomeController/actualFun/arg1/ABC
And then with the magic of routing, you can redirect actualFun/ABC to wrapperFun/ABC. So the user will only see pretty URLs.
3.- arg1 optional, arg2 optional
So you have 4 possible options, right?
somecontroller/action/arg1/arg2
somecontroller/action/arg1
somecontroller/action/arg2
somecontroller/action
I believe this is your actual question:
How do I deal with functions that have multiple optional arguments?
In this cases what you need to use are associative arrays. That is actually how CakePHP does it in many parts. It looks like this:
$arr = {"arg2" => "some val"};
// calling the function with $arr
// some_action($arr);
some_action($argArr) {
$arg1 = isset($argArr["arg1"]) ? $argArr["arg1"] : null;
$arg2 = isset($argArr["arg2"]) ? $argArr["arg2"] : null;
}
Now, about the URLs, that is for you to decide. You must have a mechanism that will tell you what value is represented by each section of the URL. What comes to mind are two options:
First, use place holders (ugly):
some_controller/some_action/arg1/non/arg3/non/arg4
Or, use wrapper actions, similar to what is seen before in my answer (ugly too).
some_controller/action5/arg5
// then in the wrapper (action5) you have:
action5(arg) {
$arr = {"arg5" => arg};
some_action($arr);
}
As you can see this can get out of hand easily. I don't know what you are actually trying to do, but it seems that you are sending data by the wrong channel.
You might want to use a POST and use an array directly, instead of building your own, check out the request object.

how to force drupal function to not use DB cache?

i have a module and i am using node_load(array('nid' => arg(1)));
now the problem is that this function keep getting its data for node_load from DB cache.
how can i force this function to not use DB cache?
Example
my link is http://mydomain.com/node/344983
now:
$node=node_load(array('nid'=>arg(1)),null,true);
echo $node->nid . " -- " arg(1);
output
435632 -- 435632
which is a randomly node id (available on the system)
and everytime i ctrl+F5 my browser i get new nid!!
Thanks for your help
Where are you calling this? For example, are you using it as part of your template.php file, as part of a page, or as an external module?
Unless you have this wrapped in a function with its own namespace, try naming the variable differently than $node -- for example, name it $my_node. Depending on the context, the 'node' name is very likely to be accessed and modified by Drupal core and other modules.
If this is happening inside of a function, try the following and let me know what the output is:
$test_node_1 = node_load(344983); // Any hard-coded $nid that actually exists
echo $test_node_1->nid;
$test_node_2 = node_load(arg(1)); // Consider using hook_menu loaders instead of arg() in the future, but that's another discussion
echo $test_node_2->nid;
$test_node_3 = menu_get_object(); // Another method that is better than arg()
echo $test_node_3->nid;
Edit:
Since you're using hook_block, I think I see your problem -- the block itself is being cached, not the node.
Try setting BLOCK_NO_CACHE or BLOCK_CACHE_PER_PAGE in hook_block, per the documentation at http://api.drupal.org/api/drupal/developer--hooks--core.php/function/hook_block/6
You should also try to avoid arg() whenever possible -- it's a little bit of a security risk, and there are better ways to accomplish just about anything arg() would do in a module environment.
Edit:*
Some sample code that shows what I'm referring to:
function foo_block ($op = 'list', $delta = 0, $edit = array()) {
switch ($op) {
case 'list':
$blocks[0] = array(
'info' => 'I am a block!',
'status' => 1,
'cache' => BLOCK_NO_CACHE // Add this line
);
return $block;
case 'view':
.....
}
}
node_load uses db_query, which uses mysql_query -- so there's no way to easily change the database's cache through that function.
But, node_load does use Drupal's static $nodes cache -- It's possible that this is your problem instead of the database's cache. You can have node_load clear that cache by calling node_load with $reset = TRUE (node_load($nid, NULL, TRUE).
Full documentation is on the node_load manual page at http://api.drupal.org/api/drupal/modules--node--node.module/function/node_load/6
I have had luck passing in the node id to node_load not in an array.
node_load(1);
According to Druapl's api this is acceptable and it looks like if you pass in an array as the first variable it's loaded as an array of conditions to match against in the database query.
The issue is not with arg(), your issue is that you have caching enabled for anonymous users.
You can switch off caching, or you can exclude your module's menu items from the cache with the cache exclude module.
edit: As you've now explained that this is a block, you can use BLOCK_NO_CACHE in hook_block to exclude your block from the block cache.

Resources