I'm having an issue with my development of a custom assetic filter. I loosely followed the steps in the blog article found here and got things working for the most part. The thing that's causing me hang up is the fact that if I make a change to the filterLoad or filterDump methods it usually shows up the first time but additional changes won't. It seems like things are getting cached but not in the usual Symfony2 cache directory. This is pretty vague so far so let me know if there's any additional information I can provide.
Example of change:
public function filterLoad(AssetInterface $asset)
{
$asset->setContent('this');
}
public function filterDump(AssetInterface $asset)
{
$asset->setContent('that');
}
Related
I am working on a project, and I would like to be able to use variables in paths directly. This may seem strange, but imagine I have
mysite.org/admin
I take precautions to stop people accessing admin, ofcourse. But for peace of mind, and the clients peace of mind, it would be nice to allow the client to choose this path, and even change it every so often.
Yes I could just change the path manually, and it would take 2 seconds, but it would just be nice if this was a possibility at all.
I'm using annotation for my routing, but I am interested in any answers if not just for curiosities sake.
Is it possible to store this in config.yml, and then use this in your path? I have been searching but not found anything on the subject.
You could do something like this:
/**
* #Route("/admin/{admin_path}")
*/
public function adminAction(Request $request, $admin_path)
{
//code to verify if admin_path is currently the good one using database or another way
if (false === is_admin_path_the_right_one($admin_path)) {
$this->redirectToRoute('index');
}
//show admin
}
I prefixed with /admin because otherwise every other route would match this action. But you could use something else like /a/
After "finish" studying Symfony2, I start to take a look to Sonata Admin and User bundles since, those bundles, could help me in some future works.
On the firsts, all seems to me terribly complicated and difficult to understd. But with few hours of architecture study, applied to real files,classes and so on, I suppose that I've understood perfectly what's the essence of that bundle and how this works.
My only "black hole" into whole thing understand is, where can I find the parameter used into sonata.user.admin.user, called sonata.user.admin.user.entity? As far I know, that parameter simply point to user class that is responsable for read/write operation from and to database.
I ask this because, after dozens of minutes spent looking, the only place where I found those information are
./app/cache/prod/appProdProjectContainer.php
./app/cache/dev/appDevDebugProjectContainer.xml
./app/cache/dev/appDevDebugProjectContainer.php
Is possible that this variable is defined only there?
If yes, because is placed into cache folder? Is loading time faster?
You should also look through Extensions in DependencyInjection folders - sometimes arguments are defined in yaml in one way, but after loading with concatenation they are transformed into another:
If in your parameters you have something like:
your_user: 'Somename'
And in DependencyInjection it is parsed as follows:
foreach($config as $key => $value) {
$container->setParameter('your.prepend.'.$key, $value);
}
Then in the end you'll have your parameter compiled with index your.prepend.your_user.
I guess, the same logic is used in mentioned bundles.
UPDATE:
Example of usage of described logic
I created an area in Visual Studio which automatically adds the appropriate bits in the "Areas" directory. I renamed this to "Modules" but now when i navigate to /{area}/{controller/{action} it still looks for the view within the /Areas/{area}/Views/{controller/{action} directory and not the /Modules/{area}/Views/{controller/{action} directory. I would also like to be able to override the view for specific themes. Therefore i was wondering how i could customise the default view engine to look for the view in the following locations aswell:
/Themes/Default/Views/{area}/{controller}/{action}.cshtml
/Modules/{area}/Views/{controller}/{action}.cshtml
I'd really appreciate it if someone could help.
Thanks
As ASP.NET MVC source code is available, it is easy to answer these kinds of questions by looking at the source. If you look at the WebFormViewEngine class you can see the locations listed and it will be easy for you to inherit from this and customise them.
However, not going with the code by convention approach is just going to make your life harder so I'd advise living with the default locations.
Here's the code incase anyone is interested:
public class CustomRazorViewEngine : RazorViewEngine {
public CustomRazorViewEngine()
: this(null) {
}
public CustomRazorViewEngine(IViewPageActivator viewPageActivator)
: base(viewPageActivator) {
AreaViewLocationFormats = new[] {
"~/Themes/Default/Views/{2}/{1}/{0}.cshtml",
"~/Themes/Default/Views/{2}/Shared/{0}.cshtml",
"~/Modules/{2}/Views/{1}/{0}.cshtml",
"~/Modules/{2}/Views/Shared/{0}.cshtml"
};
AreaMasterLocationFormats = new[] {
"~/Themes/Default/Views/{2}/{1}/{0}.cshtml",
"~/Themes/Default/Views/{2}/Shared/{0}.cshtml",
"~/Modules/{2}/Views/{1}/{0}.cshtml",
"~/Modules/{2}/Views/Shared/{0}.cshtml"
};
AreaPartialViewLocationFormats = new[] {
"~/Themes/Default/Views/{2}/{1}/{0}.cshtml",
"~/Themes/Default/Views/{2}/Shared/{0}.cshtml",
"~/Modules/{2}/Views/{1}/{0}.cshtml",
"~/Modules/{2}/Views/Shared/{0}.cshtml"
};
}
}
Now just place the following in the Application_Start event in the Global.asax.cs file:
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new CustomRazorViewEngine());
Hope this helps.
The code you posted is very similar to what I wound up doing a few months ago.
I also have a preprocessing step (run on-demand or at compile time) which finds all of the .cshtml files in the site folder hierarchy and adds their relative paths to a table in the database. The site caches that data on startup. The custom view engine then searches that list for views, and only checks the disk when it finds a match.
This performs very, very well. Avoiding disk access will probably only help if you're running a very busy site. Even though disk access is very slow, it's typically not a performance bottleneck and ASP.NET performs its own intelligent caching.
I'm visiting an app that's been in use for the past 2+ years and it is in desperate need of refactoring. It is of my own work, but you know what it's like when you visit old code again.
Anyway I've been using the excellent advice at sourcemaking to refactor and the code is already looking much better.
The problem now is there are loads of Session["variable"] sprinkled throughout the code, so what's the most accepted way to refactor these out? I found this article at code project but apparently it can be quite dangerous.
The best way to refactor random session usage like this is to create a static SessionWrapper with static properties that encapsulate the ASP.NET session store:
static class SessionWrapper
{
public static string Variable
{
get { return Session["variable"]; }
set { Session["variable"] = value; }
}
}
This will also allow you to put some logic around the getting and setting of these values and keep them in a centralized place.
I would also strongly recommend that you have some integration tests in place before you start this process so that you can be sure you haven't missed anything.
I'm new at this TDD thing but making a serious effort, so I'm hoping to get some feedback here.
I created a little web service to minify JavaScript, and everything was nice, with all my tests passing. Then I noticed a bug: if I tried to minify alert('<script>');, it would throw a HttpRequestValidationException.
So that's easy enough to fix. I'll just add [AllowHtml] to my controller. But what would be a good way to unit test that this doesn't happen in the future?
The following was my first thought:
[TestMethod]
public void Minify_DoesntChokeOnHtml()
{
try
{
using (var controller = ServiceLocator.Current.GetInstance<MinifyController>())
{
return controller.Minify("alert('<script></script>');");
}
}
catch (HttpRequestValidationException)
{
Assert.Fail("Request validation prevented HTML from existing inside the JavaScript.");
}
}
However, this doesn't work since I am just getting a controller instance and running methods on it, instead of firing up the whole ASP.NET pipeline.
What would be a good unit test for this? Maybe reflector on the controller method to see if the [AllowHtml] attribute is present? That seems very structural, and unlikely to survive a refactoring; something functional might make more sense. Any ideas?
You have only two options:
First
Write integration test that hosts MVC in-proc or runs using browser (using Watin for instance) that will cover you scenario.
Second
Write unit test that will check that method is marked with needed attribute.
I would go with the first option.