How to modify an URL in a view in CakePHP 2.x - url

It seems quite simple but there is something I am not able to figure out. I hope someone can help me fast.
I have an url, something like http://host/controller/action/argument/named:1/?query1=1. I want to add another query param to look it like http://host/controller/action/argument1/argument2/named:1/?query1=1&query2=2. I fact I want to add query2=2 to all URLs on a particular page, through some callback or something.
An URL may or may not have query params in the existing page URL.
How do I do it?

Example url : http://www.example.com/myController/myAction/param1:val1/param2:val2
You can use :
$this->redirect(array("controller" => "myController",
"action" => "myAction",
"param1" => "val1",
"param2" => "val2",
$data_can_be_passed_here),
$status,
$exit);
Hope it helps you.

May be I am thinking too much of it but here is how it came out. I put it in a UtilityHelper.
function urlmodify($params = array(), $baseurl = true) {
$top_level_1 = array('plugin', 'controller', 'action'); //top level vars
$top_level_2 = array('pass', 'named'); //top level vars
//for integrated use
$top_level = array_merge($top_level_1, $top_level_2);
$urlparams = array();
//get top level vars
foreach($top_level as $k) {
if(in_array($k, $top_level_1)) {
$urlparams[$k] = $this->request->params[$k];
}
if(in_array($k, $top_level_2)) {
$$k = $this->request->params[$k]; //create $pass & $named
}
}
//get query vars
if($this->request->query) {
$urlparams['?'] = $this->request->query;
}
//check for custom pass vars
if(isset($params['pass'])) {
$pass = array_merge($pass, $params['pass']);
}
//pass var has to be in numarical index
foreach($pass as $v) {
array_push($urlparams, $v);
}
//check for custom named vars
if(isset($params['named'])) {
$named = array_merge($named, $params['named']);
}
//pass var has to be in key=>value pair
foreach($named as $k=>$v) {
$urlparams[$k] = $v;
}
//check for custom query vars
if(isset($params['?'])) {
$urlparams['?'] = array_merge($urlparams['?'], $params['?']);
}
return Router::url($urlparams, $baseurl);
}
}
I have an URL: http://localhost/project/exlplugin/logs/manage_columns/1/a:1/n:1/?b=1. On some links I want to add some certain parameters. Here is the result when i call
echo $this->Utility->urlmodify(array('pass'=>array(2), 'named'=>array('m'=>2), '?'=>array('c'=>2)));*
It gives: http://localhost/thecontrolist/spreadsheet/logs/manage_columns/1/2/a:1/n:1/m:2?b=1&c=2
I just wanted to add just a query parameter to all my listing urls deleted=0 or deleted=1 for the SoftDelete thing :)
Thank you #u2460470 for the answer but it's just about modifying (not removing or creating anything but just adding some params to) current URL on a view page.

Related

How to pass Dictionary Objects In HttpUrl In ANgular7?

First of all i wanna say sorry for that if my question is silly question,Iam confused with this because im new in Angular.
Before asking question i want to introduce about my code,
this is the get functon that exactly i have called api,
get(feepaid_report: FeepaidReport): Observable<FeepaidReport[]> {
const options = this._utils.makeOptions(this._headers);
return this._http.get(`${this._feepaidreportUrl}`, options).pipe(
map((res: Response) => res.json()),
tap(
data => this.afterGetRequest(),
error => { console.log(error); }
));
}
Here in this code _feepaidreportUrl is my baseUrl that looks like this:
private _feepaidreportUrl = `${new Config().api}/report/feepaid_report/`;
And the my argument feepaid_report of type FeepaidReport is comes with data of dictionary like this,
FeepaidReport: {paid_date: "2019-01-03", classes: "class12"}
And i want to append this dictionary (i.e feepaidreport data) in url so that i can pass the url for backend like that:
baseurl/?paid_date=2019-01-03&classes=class12
Hope you will understand my question
Above problem is solved by doing this:
get(feepaid_report: FeepaidReport): Observable<FeepaidReport[]> {
var url = `${this._feepaidreportUrl}/?`
for(var key in feepaid_report){
var val = feepaid_report[key];
if (typeof(val) !=='undefined'){
url = url + key + '=' + val + '&'
}
}
const options = this._utils.makeOptions(this._headers);
return this._http.get(url, options).pipe(
map((res: Response) => res.json()),
tap(
data => this.afterGetRequest(),
error => { console.log(error); }
));
}

How to make angular2 custom validators to run after we get the value

If I pass hard coded values in offerCheck validator it is working fine. But if I get values from api, null values is getting passed in paramets. Form is getting executed before we get the values from service. Please help me to make validate check after getting values from api.
this.newOffer = "aaa";
this.oldOffer = "aaa";
constructor(fb: FormBuilder) {
this.formGroup = fb.group({
'offer': [null, Validators.compose([Validators.required, this.offerCheck(newOfer, oldOffer)])],
})
offerCheck(new, old) {
return (control: FormControl) => {
if (new == old) {
return true;
}
}
}
What you want is probably the AsyncValidatorFn, here's a very simple example of how to create one:
export const OfferCheck: AsyncValidatorFn = (control: AbstractControl): Observable<boolean> => {
if (new == old) {
return Observable.of(this.http.get('/some-endpoint').first().map(res => res.data));
}
};
You don't provide enough information so this is just a guess on how you'd want it to be. But it should point you in the right decision.
An alternative method would be to use setValidators of the control(s) after you've fetched the data:
this.formGroup.get('offer').setValidators([Validators.required, this.offerCheck(newOfer, oldOffer)]);
I hope this helps.

AngularFire: How to update a $firebaseArray by extending the service and using the $$updated private method

I have two separate lists of Posts and Authors in my database, each Post containing an authorId to refer to the corresponding author.
The following method helps me retrieve the whole list of Posts by systematically including the name of the author for each Post:
app.factory('NormalizedPosts', function($firebaseArray, FirebaseFactory) {
var PostsWithAuthors = $firebaseArray.$extend({
// override $$added to include author name
$$added: function(snap) {
var record = $firebaseArray.prototype.$$added.call(this, snap);
FirebaseFactory.$getAuthorId( record.authorId ).$loaded(function( authorData ) {
record.authorData = authorData;
});
return record;
},
// ????????
$$updated: function(snap) {
var rec = $firebaseArray.prototype.$$updated.call(this, snap);
var updatedRecord = this.$getRecord(snap.key());
FirebaseFactory.$getAuthorId( updatedRecord.authorId )
.$loaded(function( authorData ) {
rec.authorData = authorData;
});
return rec;
}
});
return PostsWithAuthors;
});
PS: The FirebaseFactory is just a wrapper for firebase methods.
I then call
var list = new NormalizedPosts ( new Firebase(FBURL).child("posts") );
in my controller to get the full list. This works great.
I'm scratching my head with what should go into the $$updated method: When a new Post is added, the list gets updated as expected (through the $$added method). But when there's a change in a Post data (e.g. the post title), my list does not get updated, as I'm currently returning false in the $$updated method.
Question: What should go in the $$updated method so that when theres a change in a Post data, my list gets updated accordingly (and further returns the author's name!). Thanks
I think you're going through too many loops to get something simple done.
If the name of the author is "part of" the article than you should save it:
{
"articles": {
"firebase-uniq-id-1": {
"title": "My Writing Process",
"published": "2016-01-01",
"author": {
"firebase-uniq-id-2": "Ernest Hemingway"
}
}
},
"authors": {
"firebase-uniq-id-2": {
"name": "Ernest Hemingway",
"born": "1899-07-21",
"whatever": "Some Data"
}
}
}
When you'll want to show other details about the author, fetch it.
Edit:
If you still wish to use the extension option, I believe the only thing you're missing there is extending the updateRecord with rec:
FirebaseFactory.$getAuthorId( updatedRecord.authorId )
.$loaded(function( authorData ) {
updatedRecord.authorData = authorData;
angular.extend(updatedRecord, snap.val());
});
Also, in $$updated you need to return a boolean saying if the record changed or not, and not the record itself.
Keep in mind that if you go that path you shouldn't use the default $save() method of $firebaseArray since it will also save the full authorData
$$updated: function(snap) {
// boolean for the $$updated method
var rec = $firebaseArray.prototype.$$updated.call(this, snap);
// existing record as per this
var existingRecord = this.$getRecord(snap.key());
// record as per FB database
var updatedRecord = snap.val();
if ( rec ) {
FirebaseFactory.$getAuthorId( updatedRecord.authorId )
.$loaded(function( authorData ) {
updatedRecord.authorData = authorData;
angular.extend(existingRecord, updatedRecord);
});
} // end if loop
return rec;
}

unable to pass parameter value inside Html.EditableGridView in mvc cshtml

In MVC 4 project I tried to pass parameter value like following but I failed due to syntax.
In .cshtml file
#(Html.EditableGridView<MyModel>("TestGridView",Model,Server.MapPath("~/XmlFile/Test.xml"),GridRowSelectionMode.Multiple,
new { cssObj = "genericContentCss", url = "/Test/GetMyPartial?mode=Edit&id=" }))
in url want to pass id parameter value like id=#Model.Id
but it is not working I'm missing something very small , I tried google but failed to do this can anyone give me clue
thanks
How about this:
#Html.EditableGridView<MyModel>("TestGridView",
Model,
Server.MapPath("~/XmlFile/Test.xml"),
GridRowSelectionMode.Multiple,
new { cssObj = "genericContentCss",
url = "/Test/GetMyPartial?mode=Edit&id="+Model.Id
}
)
or you can use Url.Action():
url = Url.Action("GetMyPartial","Test",new { mode="Edit" , id=Model.Id })
in above code:
#Html.EditableGridView<MyModel>("TestGridView",
Model,
Server.MapPath("~/XmlFile/Test.xml"),
GridRowSelectionMode.Multiple,
new { cssObj = "genericContentCss",
url = Url.Action("GetMyPartial","Test",new { mode="Edit" , id=Model.Id })
}
)

How to add campaign tracking data to any url automatically?

I get a bunch of different URL from my sources and what I would like is to redirect to the same URL, but with campaign data added to URL (to track the referred clicks).
For example I have these URLs:
www.example.com/category/product/name.html
www.example.com/id_product=5
I want to add at the end the following: utm_source=SOURCE&utm_medium=MEDIUM&utm_campaign=CAMPAIGN
And the URLs to become
www.example.com/category/product/name.html?utm_source=SOURCE&utm_medium=MEDIUM&utm_campaign=CAMPAIGN
www.example.com/id_product=5&utm_source=SOURCE&utm_medium=MEDIUM&utm_campaign=CAMPAIGN
How to I correctly check and cover all the cases if a URL string has parameters, and add mine?
I want to do it in node.js
Thank you
Elaborating on #snkashis, a similar but arguably more elegant solution, again using node's url module, is:
var addQueryParams = function (cleanUrl) {
var obj = url.parse(cleanUrl, true, false);
obj.query['utm_source'] = 'SOURCE';
obj.query['utm_medium'] = 'MEDIUM';
obj.query['utm_campaign'] = 'CAMPAIGN';
delete obj.search; // this makes format compose the search string out of the query object
var trackedUrl = url.format(obj);
return trackedUrl;
};
This works, because url.format first looks for search and, if it can't find it, it composes the query string from the query object
(taken from node url module documentation http://nodejs.org/api/url.html#url_url_format_urlobj )
search will be used in place of query
query (object; see querystring) will only be used if search is absent.
Here is a example showing different scenarios using Node's URL module.
var url = require('url');
var exurls = ["www.example.com/category/product/name.html","www.example.com/id_product=5?hasparam=yes"]
var to_append = "utm_source=SOURCE&utm_medium=MEDIUM&utm_campaign=CAMPAIGN";
for (i=0;i<exurls.length;i++) {
var parsedobj = url.parse(exurls[i],true,false);
//Below checks if param obj is empty.
if (Object.keys(parsedobj.query).length!==0) {
var newpath = parsedobj.href+"&"+to_append;
}
else {
var newpath = parsedobj.href+"?"+to_append;
}
console.log(newpath);
}
Connect will help you:
var connect = require('connect');
var app = connect();
app.use(connect.query());
app.use(function (req, res, next) {
console.log(req.query);
res.end(JSON.stringify(req.query));
});
app.listen(3000);

Resources