if/else Logic in Eloquent Query - if-statement

I need to be able to query a model based on specific criteria within a route closure.
I have this route:
Route::get('courses/{category_slug}/{slug}', function($category_slug, $slug) {
$category = Category::where('slug', $category_slug)->first();
$course = Course::leftJoin('categories', 'categories.id', '=', 'courses.category_id')
->where('categories.slug', '=', $category_slug)
->where('courses.slug', '=', $slug)
->orWhere('categories.parent_id', '=', $category->id)
->where('categories.slug', '=', $slug)
->firstOrFail();
return View::make('courses.show')->with('course', $course);
});
This partially works but I need to be able to either use get() or firstOrFail() depending on whether the route points to a sub-category or an actual page.
It would also be nice to change the name of the variable based on this criteria, as well as the return value to use a different blade template.
Is this approach feasible? Thanks.
UPDATE: I almost have it working using:
http://paste.laravel.com/zod
The problem is, if the query for $sub_category doesn't return anything I get a model not found error.

OK, I got it working using:
Route::get('courses/{category_slug}/{slug}', function($category_slug, $slug) {
$category = Category::where('slug', $category_slug)->first();
$sub_category = Category::where('slug', $slug)->first();
if (!is_null($sub_category)) {
if ($sub_category->slug === $slug) {
$courses = Course::leftJoin('categories', 'categories.id', '=', 'courses.category_id')
->where('categories.parent_id', '=', $category->id)
->where('categories.slug', '=', $slug)
->get();
return View::make('courses.index')->with('courses', $courses);
}
} else {
$course = Course::leftJoin('categories', 'categories.id', '=', 'courses.category_id')
->where('categories.slug', '=', $category_slug)
->where('courses.slug', '=', $slug)
->firstOrfail();
return View::make('courses.show')->with('course', $course);
}
});
There is probably a better way, so if anyone can shed some light on it that would be great.

For anyone bumping in same problem, You can use the capability of the eloquent query builder to avoid duplication:
Route::get('courses/{category_slug}/{slug}', function($category_slug, $slug) {
$category = Category::where('slug', $category_slug)->first();
$sub_category = Category::where('slug', $slug)->first();
$course_query = Course::leftJoin('categories', 'categories.id', '=', 'courses.category_id')
->where('categories.parent_id', '=', $category->id)
->where('categories.slug', '=', $slug)
if (!is_null($sub_category)) {
if ($sub_category->slug === $slug) {
$courses = $course_query->get();
return View::make('courses.index')->with('courses', $courses);
}
} else {
$course = $course_query->firstOrfail();
return View::make('courses.show')->with('course', $course);
}
});
We create a common query $course_query that we can use below many times, avoiding duplication.
Note: $course_query declaration must have no get(), firstOrFail() or first()!

Related

How to search for a particular text from list of names using if else condition in protractor?

var totalList_grps = element.all(by.css('p.group-name-text'));
totalList_grps.getText().then(function(text){
console.log('Total list of joined groups : ' + text);
});
Tried the above code for printing list of group names.
Got Output :Total list of joined groups : Party,Innovation,capsLock,Gym,Sunrisers
AW,Big Boss.
Now i need to search for a particular name using if else condition and i tried the second set of code, but its not displaying any output not even a error.
totalList_grps.getText().then(function(itemList) {
expect(itemList).toContain('Big Boss');
});
Here is developers code
1) use by.cssContainingText():
var bigBoss = element(by.cssContainingText('p.group-name-text', 'Big Boss'));
// then you can call click(), getText(), getAttribute('') on found element as following:
bigBoss.click();
2) use elements.filter():
var bigBoss = element.all(by.css('p.group-name-text'))
.filter(function(it){
return it.getText().then(function(txt){
console.log('txt: ' + txt);
return txt === 'Big Boss' || txt.includes('Big Boss');
});
})
.first();
3) use await with combination of if/else
var allNames = element.all(by.css('p.group-name-text'));
var length = await allNames.count();
var matchedIndex = -1;
for(var i=0;i<length;i++) {
var name = await allNames.get(i).getText();
if (name === 'Big Boss' || name.includes('Big Boss')) {
matchedIndex = i;
console.log('matchedIndex = ' + matchedIndex);
break;
}
}
var bigBoss = allNames.get(matchedIndex);
We can implement option 3 without using await, but the code will be not easy readable and more complex than current.
FYI, If you want to use await/async, you need to disable protractor promise management (know as control flow). You can't use both in your code at same time.

Can't get my custom template to work with my custom subclass

I'm developing a subclass of DropdownField and I'm trying to couple it with a corresponding DrodownFieldData.ss template without a success.
I flushed the cache repeatedly.
I deleted the cache folder on my localhost (XAMPP)
I moved the template around to various locations of my 'simple' theme: /simple/templates, /simple/templates/forms, /simple/templates/Includes
As you can see, the template name does not have an underscore character which has been reported to cause problems
I'm calling it as in:
return $this->customise($properties)->renderWith('DropdownFieldData');
Do you have any other ideas that I could give a try?
This is the code. It's basically a copy of DropdownField, skimmed down to the Field method.
<?php
class DropdownFieldData extends DropdownField {
public function Field($properties = array()) {
$source = $this->getSource();
$options = array();
if($source) {
// SQLMap needs this to add an empty value to the options
if(is_object($source) && $this->emptyString) {
$options[] = new ArrayData(array(
'Value' => '',
'Title' => $this->emptyString,
));
}
foreach($source as $value => $title) {
$selected = false;
if($value === '' && ($this->value === '' || $this->value === null)) {
$selected = true;
} else {
// check against value, fallback to a type check comparison when !value
if($value) {
$selected = ($value == $this->value);
} else {
$selected = ($value === $this->value) || (((string) $value) === ((string) $this->value));
}
$this->isSelected = $selected;
}
$disabled = false;
if(in_array($value, $this->disabledItems) && $title != $this->emptyString ){
$disabled = 'disabled';
}
$options[] = new ArrayData(array(
'Title' => $title,
'Value' => $value,
'Selected' => $selected,
'Disabled' => $disabled,
));
}
}
$properties = array_merge($properties, array('Options' => new ArrayList($options)));
return $this->customise($properties)->renderWith('DropdownFieldData');
// return parent::Field($properties);
}
}
I had a similar problem that was the result of timing (there was a template loaded later that replaced my own customisation, but only when using the default form template). The fix was making sure the subclassed form field had its own version of the FormField Holder method. EG:
public function FieldHolder($properties = array()) {
$obj = $properties ? $this->customise($properties) : $this;
return $obj->renderWith($this->getTemplates());
}
The template should be in templates/forms/CustomField.ss. I don't think it should matter if this is in your theme folder, in mysite, or in a module folder.
You could try the following:
rename your template DropdownFieldData_holder.ss
move DropdownFieldData_holder.ss into mysite/templates/DropdownFieldData_holder.ss
use the setFieldHolderTemplate method on your field, ie $this->setFieldHolderTemplate('DropdownFieldData_holder');
You'll also find that the fields are rendered using two templates, one of them being suffixed with '_holder', which acts as a wrapper, while the other one renders the field itself, so depending on how you want to customise your field, you might have to create both.
Have a look at the FormField class to get a better understanding on how fields are rendered, as they use a slightly different mechanism than page types
The key was to keep the template in [yourmodule]/templates, rather than in any theme's location.

#each iteration number in Ember.js or {{#index}}

According to this question, it was possible to do something like this with Handlebars rc1:
{{#each links}}
<li>{{#index}} - {{url}}</li>
{{/each}}
{{#index}} would basically give you the iteration index, which is really useful when creating tables.
When I try this with Ember.js rc3, I get an unexpected token error. Does this not work anymore? Did it ever work? Is there another way to get the iteration index?
It looks like it was possible. Can't get it to work with HBS RC3. Probably, is deprecated.
Here's a "hand written" HBS helper.
This can help you gettin the index with {{index}} and side by side you can know if the iteration in on first or last object of the Array with {{first}} and {{last}} respectively.
Ember.Handlebars.registerHelper("foreach", function(path, options) {
var ctx;
var helperName = 'foreach';
if (arguments.length === 4) {
Ember.assert("If you pass more than one argument to the foreach helper, it must be in the form #foreach foo in bar", arguments[1] === "in");
var keywordName = arguments[0];
options = arguments[3];
path = arguments[2];
helperName += ' ' + keywordName + ' in ' + path;
if (path === '') {
path = "this";
}
options.hash.keyword = keywordName;
} else if (arguments.length === 1) {
options = path;
path = 'this';
} else {
helperName += ' ' + path;
}
options.hash.dataSourceBinding = path;
// Set up emptyView as a metamorph with no tag
//options.hash.emptyViewClass = Ember._MetamorphView;
// can't rely on this default behavior when use strict
ctx = this || window;
var len = options.contexts[0][path].length;
options.helperName = options.helperName || helperName;
options.contexts[0][path].map(function(item, index) {
item.index = index;
item.first = index === 0;
item.last = index === len - 1;
})
if (options.data.insideGroup && !options.hash.groupedRows && !options.hash.itemViewClass) {
new GroupedEach(ctx, path, options).render();
} else {
return Ember.Handlebars.helpers.collection.call(ctx, Ember.Handlebars.EachView, options);
}
});
and this can be tested like
{{#foreach array}}
{{log index first last}}
{{/foreach}}
i had the same problem recently i finish by writing a bound helper and passing them objects via Binding for example item here is an ember DS.Store object and content is a 'content' of the controller. hope it
Ember.Handlebars.registerBoundHelper 'isPair', (content, options)->
item = options.hash.item
content_name = options.hash.content || 'content'
if #get(content_name).indexOf(item) % 2 == 0 then 'is-pair' else 'is-unpair'
and in you view you call it
{{isPair content itemBinding='order'}}
i don't know if it is what you looking for but it might give you some ideas how to use it in your project.
btw. Ember overwrites #each helper that's why there it no #index i suppose

Setting Custom Privacy for FB graph API posts to feed stopped working

It worked perfectly fine for a few month, but suddenly stopped recognizing CUSTOM privacy settings. If custom settings allows a list of friends, get a "friends value was not recognized" error, if it denies list of friends, privacy is simply set to "SELF".
$custom = ',"friends": "SOME_FRIENDS","allow": "' + $ids + '"';
var params = {};
params['message'] = $message;
params['name'] = $name;
params['link'] = $url;
params['caption'] = $caption;
params['privacy'] = '{"value":"'+$privacy + '"' + $custom + '}';
FB.api('/me/feed', 'post', params, function(response) {
if (!response || response.error) {
alert(response.error.message);
} else {
if (response && response.id) {
alert("success");
}
});
Anyone ran into this issue? Any help is appreciated!

Posting to a multiple friends walls with FB graph API

I have this code:
function graphStreamPublish(){
var params = {};
params['message'] = '';
params['name'] = '';
params['description'] = '';
params['link'] = '';
params['picture'] = '';
params['caption'] = '';
FB.api('/me/feed', 'post', params, function(response) {
if (!response || response.error) {
alert('Error occured');
} else { }
which works awesome and it posts to my wall or my friend's wall when I change /me/feed to /MY_FRIENDS_ID/feed
But what I want is to post to 25 friends at a time (with one click) by randomly selecting my friends IDs .
Is there any PHP code or anything that can do that? For example accessing and extracting my friends IDs to a some kind of file and then putting them in to the /FRIENDS_ID/feed code?
Sorry for my english. I just started to learn facebook apps yesterday, sorry if I sound too amateur.
I heard there is some php code called 'loop' and it works... Please if anyone can help me. I would appreciate that!
First, you can get all friends IDs using the API. You can then select 25 random indices from that array.
Here is an example of how to do it:
Getting a random value from a JavaScript array
You can then iterate through the (randomly) selected indices, and for each iteration, you can do the FB.api call.
The graphStreamPublish could take one parameter, which is the ID of the person whose wall you want to post to, so it could look something like this:
function graphStreamPublish(targetID) {
var params = {};
params['message'] = '';
params['name'] = '';
params['description'] = '';
params['link'] = '';
params['picture'] = '';
params['caption'] = '';
FB.api('/' + targetID +'/feed', 'post', params, function(response) {
if (!response || response.error) {
alert('Error occured');
} else {});
Also, I'm thinking the params object can also be sent as a parameter.
And finally, here's how this function would look in the mentioned context:
for(i = 0; i < selectedFriendIDs.length; i++)
graphStreamPublish(selectedFriendIDs[i]);
Hope this helps. Have a great day!