Yii2 class not found when moving application to live server - yii2

My application works perfectly locally however upon uploading to live server there's a couple of issues.
The first one is I get the following error on one specific page of my application but not on other that user the same class.
Class 'yii\helpers\url' not found
The above error is found even though I have the below line at the top of my view file.
use yii\helpers\url;
The other issue I get is when trying to locate a record within my Seo table using my Seo model however this error again only occurs on one part of my application but not the other part that uses the same table/model. Below is the error I get:
Class 'common\models\seo' not found
When I use the following line (I can confirm table relations work and the necessary data is their)
$seo = Seo::find()->where(['id' => $model->seo_id])->one();

use yii\helpers\url;
change to
use yii\helpers\Url;
The same way seo class name will be started using capital case
Seo

Related

.NET CORE 3 Upgrade CORS and Json(cycle) XMLHttpRequest Error

I had my working project written in asp.net core 2.1 for a long time, but yesterday, I was forced to upgrade it to .net core 3.0 (due to 2.1 cannot call Dll' s which are written in 3.0 already).
With that, a lot of functions were obsolete or already removed. I fixed almost all of it, but one problem with CORS.
Like many people before me, I used:
app.UseCors(x => x
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
in Configure function. And services.AddCors() in ConfigureServices function.
I was able to fixed this quite easily with setting WithOrigins() or .SetIsOriginAllowed(_ => true) instead of AllowAnyOrigin() which does not work anymore with AllowCredentials().
After that, I was able to start the application and I thought everything is fine, but then I get stuck until now with problem I do not know, how to fix.
I have DB relation N:N and relation table which handle that, that means I have Admin entity with AdminProject list property, then I have AdminProject entity with Admin list and Project list properties and Project entity with AdminProject list property once again.
When I am listing my projects of certain admin, I am returning in Controller this return Ok(projects), where I just use getAll on AdminProject entity and then with Select return only project.
For that, I have to use[JsonIgnore] in project/admin for properties which I do not need to avoid cycling when creating json.
With that said: NOW IN .NET CORE 3.0 AND CORS SETTINGS IT DOES NOT WORK.
I am getting an error:
System.Text.Json.JsonException: A possible object cycle was detected which is not supported. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 32.
when debugging in console and error Access to XMLHttpRequest at 'http://localhost:5000/api/project/adminlist/1' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. in WEB browser
I think I tried almost everything with Cors settings etc and I do not know why is this happening now. I also tried to JsonConvert.SerializeObject() before return it ---> return Ok(JsonConvert.SerializeObject(projects)) and this is working, but I am not able (mentally) to do this in every single controllers functions.
Please help! Thanks a lot!
The problem was occurring because in .NET Core 3 they change little bit the JSON politics. Json.Net is not longer supported and if you want to used all Json options, you have to download this Nuget: Microsoft.AspNetCore.Mvc.NewtonsoftJson.
After that in your Startup.cs file change/fix/add line where you are adding MVC (in the ConfigureServices method.
So: here is what I did and what fixed my issue:
services.AddMvc(option => option.EnableEndpointRouting = false)
.SetCompatibilityVersion(CompatibilityVersion.Version_3_0)
.AddNewtonsoftJson(opt => opt.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore);
I hope it will help somebody else.
Cheers!
A couple other things have changed in .net core 3 and now instead of using addMVC you can use addControllers. So your code might look like the follow:
services.AddControllers().AddNewtonsoftJson(x => x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);

Custom JSON renderer in AEM/Sling

I've been playing around with this for a while now, and I think, I've - almost - cracked it, but I am still not fully satisfied with my solution.
So, what I want to do, is having a piece of content, a list of items, which would have two views: The standard HTML one, so people can view and edit it; and then a JSON endpoint for other services to consume.
First I thought it's a simple matter of creating two JSP scripts to render the content:
/apps/my-stuff/components/list-page/html.jsp
/apps/my-stuff/components/list-page/json.jsp
However the Apache Sling DefaultServlet seems to be rather ignorant of the json.jsp script.
As a second attempt, I created another script, in /apps/foundation/components/primary/cq/Page/json.jsp which will be actually called, and renders the page, as I expected. However there are a couple of worries/questions regarding this:
First of all, why is this being honoured by the system, and not the one in the more specific place?
The documentation states, that to find the appropriate renderer, first sling:resourceType will be inspected, then sling:resourceSuperType and then, only as a fallback will jcr:PrimaryType checked. However I think this is rather: jcr:PrimaryType, then the DefaultServlet, and then all the other things.
Most worryingly however, I have to admit, this is rather generic, so it'll break all the contnet with jcr:PrmaryType = Page, so that could have some side-effects.
A solution could be creating a new type: ListPage extends Page; and then create a renderer for that in /apps/foundation.... However I have this bad feeling, that might introduce other problems.
So my question is two fold: What is the proper way of doing this, and/or what am I missing from the way the URL -> script resolution is working in AEM/Sling. (Because it seems to be slightly different that described here and here.)
(Obviously I am trying to keep the default JSON renderer for other pages, as that might be needed for other things in the page. I am not even sure, changing this one page won't break the UI for this particular page...)
However the Apache Sling DefaultServlet seems to be rather ignorant of the json.jsp script.
Have you tried renaming your JSP like so: "list-page.json.jsp"?
If you're using AEM 6.3, you should look at Sling model Exporters. They allow you to automatically register a servlet against your Sling Model (that you can create to model your list content). That servlet can generate a JSON representation of the model for you using Jackson.
If you're not using AEM 6.3, I would suggest you create a servlet registered against your resource type and use an additional selector.
#SlingServlet(
selectors = "json",
resourceType = "my-stuff/components/list-page",
methods = "GET")
More information on Sling Servlets can be found here.

How to have class loaded without using "use" but call it as if I used it

I have studied these 2 sources, but none of those works for me.
http://www.yiiframework.com/doc-2.0/guide-concept-autoloading.html
Yii2 - How do I AutoLoad a custom class?
I have created custom helper class which I want to include in every model, controller and view in my application. I am using Yii2 advanced app version 2.0.11, IDE I am using is PHPStorm
QUESTION:
What I want to achieve is to not use use keyword at the beggining of every class but still be able to simply call AppHelper::myMethod() in models, controllers and views.
How is that possible?
Closest I got it working was using this solution https://stackoverflow.com/a/35160997/5395463
All other solutions did not work for me. I am getting errors like:
PHP Fatal Error – yii\base\ErrorException
Class 'frontend\controllers\AppHelper' not found
when I simply dont include use commons\commands\AppHelper;
or when not using namespace as they suggest there with other settings:
Fatal error: Uncaught exception 'yii\base\UnknownClassException'
with message 'Unable to find 'common\commands\AppHelper'
in file: C:\xampp\htdocs\domain.com\web\common/commands/AppHelper.php.
Namespace missing?' in ...
SOLUTION:
Thanks for your responses, I got it working finaly. https://stackoverflow.com/a/42330631/5395463 solution works best for me.
So I removed namespace from that class, but left it in common\commands folder, added require to frontend/web/index.php and backend/web/index.php files (not sure if I should add it to yii file in root too, I didnt, so far it is working good anyways), and changed calls of class from AppHelper::myMethod() to \AppHelper::myMethod() looks like eveything is working now.
In Yii2 You can use an explicit way adding \ to full namespaced name
\frontend\controllers\AppHelper
so you can sue your method
\frontend\controllers\AppHelper::yourMethod();
Solution for not lazy coders:
create component with your class so you can use it like \Yii::$app->my_component
if even this is too much and your IDE is better than Windows Notepad prepare macro that will print this for you
Solution for lazy coders:
Save your class in single PHP file without namespace.
Modify you entry script to include this class - i.e. for Basic Project Template it's /web/index.php; add there
require(__DIR__ . '/path/to/MyClass.php');
For Advanced Project Template modify it properly.
Now you can use your class by calling it like \MyClass (yes, \ is required and yes, your IDE probably will modify it anyway to MyClass with use MyClass; added at the beginning.

Grails package change for domain class caused DuplicateMappingException

While working through a tutorial to start learning Grails, I made a mistake and ran:
grails create-domain-class com.FooBar
instead of:
grails create-domain-class com.acme.FooBar
It was immediately obvious I had made an error so I tried the following:
Searched for a function that reverses the create-domain-class command, it seems there isn't one.
Searched for advice on the web and the consensus is that you can delete a domain class file, any associated views and tests, then to be safe run a text search for your class name in your project directory for any references you may have missed. I have done all this.
Then I ran the correct command to create com.acme.FooBar, which worked.
After this the app fails to run and reports the following error:
org.hibernate.DuplicateMappingException: duplicate import: FooBar refers to both com.acme.FooBar and com.FooBar (try using auto-import="false")
After adding the following code to com.acme.FooBar:
...
static mapping = {
autoImport false
}
...
The app now runs as expected.
However as an experienced Java developer who occasionally does refactor a package I would like to understand how to do that without causing a DuplicateMappingException or resorting to the "autoImport false" solution.
Thanks.
You shouldn't be doing
static mapping = {
autoImport false
}
As, by doing this you said that don't check for domain just by name and look up for package as well. Hence, once you do that you will have to use Fully qualified name of the class in your queries / hqls which may itch sometimes.
You should be removing the Domain completely i.e.
remove the Domain
remove the view folder creating by default with very same name and so do the controller
Now, do grails clean-all(Make it a thumb rule to use grails clean-all first for any issue unexpectedly occuring).
To be more accurate do remove target directory from your project and then do run grails run-app.
I had done very same thing many times and got it resolved by above steps.
Hope it helps.

How do I get the absolute media file path in umbraco using razor?

I've tried the following bit of razor code:
#room.Media("summaryImage","umbracoFile")
but I get something like ~/media/155/lux.jpg, how do I remove the initial ~ to get a server path ie, /media/155/lux.jpg or http://some_url/media/155/lux.jpg?
EDIT:
I've tried
#{
dynamic summaryImagePath = room.Media("summaryImage","umbracoFile");
}
#Page.ResolveUrl(#summaryImagePath)
and
#Page.ResolveUrl(#room.Media("summaryImage","umbracoFile"))
but I keep getting the error:
Error loading Razor Script Cannot perform runtime binding on a null reference
even though #room.Media("summaryImage","umbracoFile") gives ~/media/155/lux.jpg.
Any ideas?
I'm not sure whether there is a solution within Umbraco, I'd just use the .NET framework. With ASP.NET, you can use MapPath to resolve virtual paths to physical file paths:
#HttpContext.Current.Server.MapPath(room.Media("summaryImage","umbracoFile"))
EDIT:
If you are looking for the absolute URL, you may use one of the following variants:
#Page.ResolveUrl(room.Media("summaryImage","umbracoFile"))
or
#VirtualPathUtility.ToAbsolute(room.Media("summaryImage","umbracoFile"))
You may would like to read this article about different approaches for resolving URLs.