Does any one has an idea about this. I don't know why it is showing duplicated queries. I searched a lot, found one answer on stackoverflow, but didn't get proper answer. If anyone faced the same error then please let me know. Thank you
protected $_param;
public function __construct(Utility $utility)
{
$league = $utility->checkDomainController();
view()->share('league', $league);
$this->league = $league;
}
This is the code in controller. which shares league to all the views. But there is only one query in $league = $utility->checkDomainController();
Here is the checkDomainController
if(\Request::server('HTTP_HOST') == env('MAIN_DOMAIN'))
{
$leagueSlug = Route::current()->getParameter('league');
$league = League::where('url', $leagueSlug)->first();
}
else
{
$league = League::where('custom_domain', \Request::server('HTTP_HOST'))->first();
}
if(!$league)
{
//error page
}
return $league;
Anytime you call a property which relies on a related model in blade, Laravel executes a new query, unless you eager load and pass from the controller to the view the preloaded data.
This example you posted seems to me as a loop somewhere within your blade code. Maybe if you can share a bit more of the code related to the front-end, I can help you figure it out.
Related
I have a small blog app that has Articles and Tags. Nothing fancy so far. Every Article can have many Tags.
The Laravel backend delivers the data via API calls from Axios in the Vue Frontend. In the Laravel models Article has a method
public function tags(){
return $this->belongsToMany('App\Tag');
}
and vice versa for tags. I have a pivot table and all this follow pretty much the example given in https://laracasts.com/series/laravel-5-fundamentals/episodes/21
All this works fine.
Now let´s say I want to call in Vue the method deleteTag() which should remove the connection between Article and Tag. Things are behind the scenes a bit more complicated as "addTag" in PHP also adds a new Tag Model AND the connection between Tag and Article in the Pivot table OR connects - if the Tag exists already - an existing Tag with Article.
What is the best way to achieve this?
What I´m doing so far:
ArticleTags.vue
deleteTag(tagName){
let articleId = this.articleId;
this.$store.dispatch('removeTagFromArticle', { articleId, tagName });
},
index.js (Vuex store)
actions: {
removeTagFromArticle(context,param) {
axios.post('api/articles/delete-tag/', param)
.then((res) => {
let article = context.getters.getArticleById(param.articleId);
let tagName = param.tagName;
context.commit('deleteTag', {article, tagName} );
})
.catch((err) => console.error(err));
} }
mutations : { deleteTag (state, { article, tag }) {
let tagIndex = article.tags.indexOf(tag);
article.tags.splice(tagIndex,1);
} }
ArticleController.php
/**
* Remove Tag from Article
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function deleteTag(Request $request)
{
$tag = \App\Tag::firstOrCreate(array('name' => $request->tagName));
$article = Article::findOrFail($request->articleId);
$result = $article->tags()->detach([$tag->id]);
$this->cleanUpTags();
return response('true', 200);
}
routes/web.php
Route::post('api/articles/delete-tag', 'ArticleController#deleteTag');
This works so far. The code does exactly what it should. Only it feels really clumsy. And probably to complicated. Maybe it´s because the example is simple but the whole setup is big.
Nonetheless I´m trying to improve my coding. :)
So my questions are:
1) Would it be better to pass the article object in Vue to the store instead of the articleId?
2) Is the idea of using Array.slice() in the store too complicated? This could be done straight in the components.
3) Does it make sense to reload the whole store from Laravel after deleting the tag PHP-wise?
Edit: in case someone is looking for this question and how I solved it at the end. The source code for this app can be found at https://github.com/shopfreelancer/streamyourconsciousness-laravel
Personally I like to use ID's to reference any database resource aswell as keeping my objects in javascript somewhat the same as my API.
1
In this case I would have changed my tags to objects instead of strings and send an ID of the tag to my API.
An example of my article would look like:
let article = {
tags: [{ id: 1, name: 'tag 1' }, { id: 2 ... }]
}
Using objects or IDs as parameters are in my opinion both fine. I should stick with objects if you like "cleaner" code, there will only be one place to check if the ID is present in your object aswell as the selection of the ID.
Case:
// Somehwere in code
this.deleteArticle(article);
// Somehwere else in code
this.deleteArticle(article);
// Somewhere else in code
this.deleteArticle(article);
// Function
deleteArticle(article) {
// This check or other code will only be here instead of 3 times in code
if (!article.hasOwnProperty('id')) {
console.error('No id!');
}
let id = article.id;
...
}
2
Normally I would keep the logic of changing variables in the components where they are first initialized. So where you first tell this.article = someApiData;. Have a function in there that handles the final removal of the deleted tag.
3
If you are looking for ultimate world domination performance I would remove the tag in javascript. You could also just send the updated list of tags back in the response and update all tags of the article with this data and keep your code slim. However I still like to slice() the deleted tag from the array.
Remember this is my opinion. Your choises are completely fine and you should, like I do myself, never stop questioning yours and others code.
I got problem about session data, in my web, i want to make a different view based on previledge user, here my code in controller :
$previledge = $this->session->userdata['previledge'];
$data['previledge']=$previledge;
if($data['previledge'] == 'admin'){
$this->load->view("app_admin/global/header",$d);
$this->load->view("app_admin/materi/home");
$this->load->view("app_admin/global/footer");
}
else {
$this->load->view("app_admin/global/header2",$d);
$this->load->view("app_admin/materi/home");
$this->load->view("app_admin/global/footer");
}
}
if i run my code above, previledge with admin can't go to the right view.
if there any suggestion, please inform,
thanks
Its something like syntax error.
$previledge = $this->session->userdata('previledge');
This will help you.
Below code must have to work
$this->session->userdata('previledge')=='admin'
So my problem is that my validation errors are being deleted from my domain object before I can render them on the page. I thought I had fixed this error in the past, but it has crept up on me again.
Here is a look at my original implementation. The errors were being cleared when tripService.stepData(trip) was being called.
Edit- I should not that I only experienced this issue when the page adds to a hasMany relationship.
Controller -
Trip trip = tripService.savePrePaymentInfo(params)
if (trip.hasErrors()) {
render(view: "step4", model: tripService.stepData(trip))
}
else {
redirect(action: trip.status.action, id:trip.id)
}
Service -
Map stepData(Trip trip)
{
Map returnSet = [:]
returnSet.status = Status.findAllByActionNotEqual("review")
returnSet.trip = trip
returnSet
}
So I did some reading online and someone one on a forum post like 2 years ago said there was something in hibernate..possible bug... I don't know, but their suggestion worked. The suggestion was to wrap the controller in a withTransaction:
Trip.withTransaction {
//Controller code here
}
This has been working for me fine. The issue now is that I have a taglib in my view that calls tripService again. When that call is being made it is now clearing my validation errors. This is getting really frustrating. Does anyone have ANY idea on what I can do to resolve this?
Edit: Adding service method being called from taglib:
String findBannerName(Long pidm, String format = 'LFMI')
{
"abc"
//It really doesnt matter what is here - tried just returning this string and it produced the issue
}
Are you sure the trip.errors property is populated in the first place?
Also, which tripService method are you calling in the taglib?
I was wondering if someone could help me out.
Im building a forum into my codeigniter application and im having a little trouble figuring out how i build the segments.
As per the CI userguide the uri is built as follows
www.application.com/CLASS/METHOD/ARGUMENTS
This is fine except i need to structure that part a bit different.
In my forum i have categories and posts, so to view a category the following url is used
www.application.com/forums
This is fine as its the class name, but i want to have the next segment dynamic, for instance if i have a category called 'mycategory' and a post by the name of 'this-is-my-first-post', then the structure SHOULD be
www.application.com/forums/mycategory/this-is-my-first-post
I cant seem to achieve that because as per the documentation the 'mycategory' needs to be a method, even if i was to do something like /forums/category/mycategory/this-is-my-first-post it still gets confusing.
If anyone has ever done something like this before, could they shed a little light on it for me please, im quite stuck on this.
Cheers,
Nothing is confusing in the document but you are a little bit confused. Let me give you some suggestions.
You create a view where you create hyperlinks to be clicked and in the hyperlink you provide this instruction
First Post
In the controller you can easily get this
$category = $this->uri->segment(3);
$post = $this->uri->segment(4);
And now you can proceed.
If you think your requirements are something else you can use a hack i have created a method for this which dynamically assign segments.
Go to system/core/uri.php and add this method
function assing_segment($n,$num)
{
$this->segments[$n] = $num;
return $this->segments[$n];
}
How to use
$this->uri->assign_segment(3,'mycategory');
$this->uri->assign_segment(4,'this-is-my-first-post');
And if you have error 'The uri you submitted has disallowed characters' then go to application/config/config.php and add - to this
$config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-';
You could make a route that forwards to a lookup function.
For example in your routes.php add a line something like;
$route['product/(:any)/(:any)'] = "forums/cat_lookup/$1/$2";
This function would then do a database lookup to find the category.
...
public function cat_lookup($cat, $post) {
$catid = $this->forum_model->get_by_name($cat);
if ($catid == FALSE) {
redirect('/home');
}
$post_id = $this->post_model->get_by_name($post);
/* whatever else you want */
// then call the function you want or load the view
$this->load->view('show_post');
}
...
This method will keep the url looking as you want and handle any problems if the category does not exist.Don't forget you can store the category/posts in your database using underscores and use the uri_title() function to make them pretty,
Set in within config/routes.php
$route['song-album/(:any)/:num'] = 'Home/song_album/$id';
fetch in function with help of uri segment.
$this->uri->segment(1);
isn't this the right method to get Name of logged in customer?
<?php echo Mage::helper('customer')->getCustomer()->getName(); ?>
I have a website with live chat functionality. Yesterday I have been asked to pass email address and the name of the logged into the user into the Javascript Tracking variable code placed in the head section of the website. So that the operators could see who is on the website and whom are they talking to without any need to ask about their information.
So I passed the information from Magento into the Javascript code but now I see this very strange thing happening. For example,
If I am logged in with credentials Name = John Email =
john12#yahoo.com
Then This name and email variable values are changing with the change of pages. For example if I click on any product page the variable values which I am passing changes to some other user's information.
Name becomes Ricky Email becomes ricky23#gmail.com
this variable values are kept on changing back to john and from john to something else with the change of pages. So operator does not have any idea whom are they talking because the values are kept on changing. Also, user ricky or who ever it changes to also exist in the database. so it is picking up random person from the database.
This is what i did to pass the code to javascript. Please let me know if that is not the right code to pass the information. Please check the php code I am using to fetch information from Magento. Roughly, I receive incorrect value once in 5 times. Please provide some assistance. Thanks in advance.
<?php
$customer = Mage::getSingleton('customer/session')->getCustomer();
$email = $customer->getEmail();
$firstname = $customer->getFirstname();
$lastname= $customer->getLastname();
$name = $firstname . ' ' . $lastname;
?>
<script type="text/javascript">
if (typeof(lpMTagConfig) == "undefined"){ lpMTagConfig = {};}
if (typeof(lpMTagConfig.visitorVar) == "undefined"){ lpMTagConfig.visitorVar = [];}
lpMTagConfig.visitorVar[lpMTagConfig.visitorVar.length] = 'Email=<?php echo $email; ?>';
lpMTagConfig.visitorVar[lpMTagConfig.visitorVar.length] = 'Name=<?php echo $name; ?>';
</script>
I'm also attaching a snap shot
I'd be interested to hear how you're adding this code to the page? Is it in it's own block, or are you adding it to footer.phtml, or similar? If your adding to an existing block be sure to check the block caching settings of that template.
To confirm the caching hypothesis I'd ask the following:
Do you get the same name, all the time, on the same page? When you refresh the page, do you get the same name and email in the Javascript?
Does the problem persist with caching disabled?
This doesn't sound like a singleton problem at all. Each execution of the PHP script is isolated from the others, serving one page request. There's no chance of another customer's object moving between invokations of the script.
It is a matter of understanding the singleton pattern. If you call your code twice:
$customer_1 = Mage::helper('customer')->getCustomer()->getName();
$customer_2 = Mage::helper('customer')->getCustomer()->getName();
you get two different instances of the object. But... if one of them has already implemented a singleton pattern in its constructor or has implemented a singleton getInstance then both objects will actually point to the same thing.
Looking at the customer/helper/Data.php code you can see the function
public function getCustomer()
{
if (empty($this->_customer)) {
$this->_customer = Mage::getSingleton('customer/session')->getCustomer();
}
return $this->_customer;
}
That means that in one of the cases singleton is already implemented/called and in other one - not as the property is already set.
The correct way to work with quote/customer/cart in order to get always the correct data is always to use the singleton pattern.
So using this:
$customer = Mage::getSingleton('customer/session')->getCustomer();
always guarantee that you get the correct customer in that session. And as may be you know singleton pattern is based on registry pattern in app/Mage.php:
public static function getSingleton($modelClass='', array $arguments=array())
{
$registryKey = '_singleton/'.$modelClass;
if (!self::registry($registryKey)) {
self::register($registryKey, self::getModel($modelClass, $arguments));
}
return self::registry($registryKey);
}
and looking at app/Mage.php:
public static function register($key, $value, $graceful = false)
{
if (isset(self::$_registry[$key])) {
if ($graceful) {
return;
}
self::throwException('Mage registry key "'.$key.'" already exists');
}
self::$_registry[$key] = $value;
}
...
public static function registry($key)
{
if (isset(self::$_registry[$key])) {
return self::$_registry[$key];
}
return null;
}
you can see that Magento checks is it is already set. If so, Magento will either throw an Exception, which is the default behavior or return null.
Hope this will help you to understand the issue you face.
I have sorted this out. I have moved the code from footer.phtml to head.phtml and it's working fine now.Values are not changing anymore. If anyone know the logic behind please post and I will change my answer. So far this is working.