The issue is, I would like to use all benefits of tasks runner and bower into my existing Zend-Project. I'm not sure, how should I restructure my whole project folder.
My current structure looks like follows:
config
module
vendor
public
css
js
libs
jquery
bootstrap
controller1
jsController1.
etc
index.php
From this (Gulp and Bower - creating proper files structure) I know, that I have to create a separate folder to save all libraries installed from bower and then I have to copy them with gulp into the public folder. Now depending on enviroment (Production or Development) I want to use minified css and js scripts. So should I create 2 public - folders and depending on enviroment change base path for zend? Or what's the best way to perform that?
Additionally I would like to integrate browser-sync into this project (cause of livereload). Therefore I want to use gulp-connect to start the php-server. But then the enviroment variables from apache are not set. How can I set it? According to documentation I have to add newArgs (cause my Options are array) "APPLICATION_ENV=development". But if add this after comma, i get error: "Could not open input file: APPLICATION_ENV=development"
My currenty gulfile:
var gulp = require('gulp'),
php = require('gulp-connect-php');
gulp.task('php', function() {
php.server({
configCallback: function _configCallback(type, collection) {
// If you wish to leave one of the argument types alone, simply return the passed in collection.
if (type === php.OPTIONS_SPAWN_OBJ) { // As the constant suggests, collection is an Object.
// Lets add a custom env var. Good for injecting AWS_RDS config variables.
collection.env = Object.assign({
APPLICATION_ENV: "development"
}, process.env);
return collection;
} else if (type === php.OPTIONS_PHP_CLI_ARR) { // As the constant suggests, collection is an Array.
let newArgs = [
'-e', // Generate extended information for debugger/profiler.
'-d', 'memory_limit=2G' // Define INI entry, Up memory limit to 2G.
,"APPLICATION_ENV=development"
];
// Ensure our argument switches appear before the rest.
return newArgs.concat(collection);
}
}
,
base: 'public',
port: 8010,
keepalive: true},
function _connected_callback() {
console.log("PHP Development Server Connected.");
});
}
);
Related
My website is with a hosting provider that has the MessageFormatter class available on the server (Linux, PHP 7.0.27) but it is an old ICU version (4.2.1) that doesn't support my message {number,plural,=0{# available} =1{# available} other{# available}} and gives the error:
Message pattern is invalid: Constructor failed
msgfmt_create: message formatter creation failed: U_ILLEGAL_CHARACTER
...because of the =1 and =2 notation.
I'm not able to make changes to the server so how can I force using the fallback method provided by Yii2 which works just fine?
There is this hacky way you can try.
Copy the yii\i18n\MessageFormatter code to a new file. Name it MessageFormatter.php and place somewhere in your application (but not in vendor folder).
In this new file change the format() method to:
public function format($pattern, $params, $language)
{
$this->_errorCode = 0;
$this->_errorMessage = '';
if ($params === []) {
return $pattern;
}
return $this->fallbackFormat($pattern, $params, $language);
}
Don't change anything else (including namespace).
Now let's use Yii mapping.
Find a place in your application when you can put code that will be run every time in bootstrapping phase. Good place for this is common/config/bootstrap.php if you are using "Advanced Template"-like project.
Add there this line:
Yii::$classMap['yii\i18n\MessageFormatter'] = 'path/to/your/MessageFormatter.php';
Obviously change the path to the one you've chosen. Now Yii autoloader will load this class from your file instead of the original Yii vendor folder (as mentioned in Class Autoloading section of the Guide).
In the modified file MessageFormatter method presence of intl library is never checked so fallback is used as default.
The downside of this trick is that you need to update manually your file every time original Yii file is changed (so almost every time you upgrade Yii version).
Another approach is to configure I18N component in your application to use your custom MessageFormatter where you can extend the original file and just override format() method inside without modifying class map.
Let's say i have one codebase for 500+ clients, based on load balanced web-servers. Each client has their own database, and therefor their own set of credentials.
The easy way here would be to have different .env files with each of the clients credentials and enviornmental settings (this works fine btw), but for optimization reasons, i would like to run the "artisan cache:config" method. This will compile all the config files into a single "config.php" file in /bootstrap/cache".
Now, this is not very functional with lot's of clients. I's it possible to tell Laravel WHERE to look for the cached config file? Without changing core code?
Like defining an enviornmental variable from the vhost "CONFIG_PATH" and (pseudo code)
if( null !== getenv("CONFIG_PATH") && getenv("CONFIG_PATH") != "" ) {
$app->bootstrapConfigPath( getenv("CONFIG_PATH") );
}
Or is the only possibility to have alot of directories, with each their "Bootstrap/cache" folder, and symlinks to the shared codebase ( Which in my opinion is a rather cumberstone path to walk down )
Thanks in advance.
This is possible, but you need to complete a couple of steps. Firstly by extending Illuminate\Foundation\Application with your own application class and overriding the bootstrapPath() method. Then you also have to symlink back to the original bootstrap/app.php from your custom bootstrap folder.
Example
Step 1
/app/Applications/MyApp.php - new custom app class
<?php
namespace App\Applications;
use Illuminate\Foundation\Application as Laravel;
class MyApp extends Laravel
{
public function bootstrapPath($path = '')
{
$bootstrap_env = getenv('APP_BOOTSTRAP');
if(!$bootstrap_env || !file_exists($bootstrap_env) || !file_exists($bootstrap_env.'/app.php')){
dd("Install incomplete, please set bootstrap folder via APP_BOOTSTRAP, make sure the folder exists and the app.php is sym linked");
}
return $bootstrap_env;
}
}
Step 2
/app/bootstrap/app.php - update to instantiate new custom class
- $app = new Illuminate\Foundation\Application(
- realpath(__DIR__.'/../')
- );
+ $app = new App\Applications\MyApp(
+ realpath(__DIR__.'/../')
+ );
Finally
Create custom folders (make sure they are writeable) and a symbolic link of the current app.php to the custom bootstrap location.
mkdir -p /mycustomlocation/bootstrap/cache/
ln -s /laravel/install/bootstrap/app.php /mycustomlocation/bootstrap/app.php
*We couple this with setting a custom .env location using theuseEnvironmentPath() method on the instantiated $app also.
So I want to use the benefits of CSSModules in a regular PHP project (a wordpress theme to be more specific). I am using webpack with autoprefixer, browsersync, postcss and more to compile and hot reload parts of the project while developing. I understand that there is also a plugin to postcss called postcss-modules which I would like to use.
The plugin is adding hashes to all my css classes and outputting a json with the mappings, as expected. Now I would like to bind one css module (which is a scss-file uncompiled) to each php file (as you would do when using css modules in React). How should I do this? I would still like the css to resist in one large file after compiling.
This is a part of my webpack config:
{
test: /\.(scss|css)$/,
use: extractSass.extract({
use: [{
loader: "css-loader"
},
{
loader: 'postcss-loader',
options: {
plugins: function () {
return [
require('precss'),
require('autoprefixer'),
require('cssnano'),
require('postcss-modules')
];
}
}
},
{
loader: "sass-loader"
}],
fallback: "style-loader"
})
},
And I am using a main.js and a style.scss as entry point in webpack. The style.scss is then importing all the partial scss-files (which should be one css module each).
I did a really good writeup on how to do all this. The only difference is I am using grunt-postcss instead of Webpack to handle the postcss plugins and functionality. Should be straightforward to port the concepts over to Webpack.
The key is to configure postcss-modules to handle the separate pcss files as modules. That way you can parse the JSON separately per module. Using globalModulePaths you are able to keep your main pcss intact and append your modules to it.
I have a Yaml loader that loads additional config items for a "profile" (where one application can use different profiles, e.g. for different local editions of the same site).
My loader is very simple:
# YamlProfileLoader.php
use Symfony\Component\Config\Loader\FileLoader;
use Symfony\Component\Yaml\Yaml;
class YamlProfileLoader extends FileLoader
{
public function load($resource, $type = null)
{
$configValues = Yaml::parse($resource);
return $configValues;
}
public function supports($resource, $type = null)
{
return is_string($resource) && 'yml' === pathinfo(
$resource,
PATHINFO_EXTENSION
);
}
}
The loader is used more or less like this (simplified a bit, because there is caching too):
$loaderResolver = new LoaderResolver(array(new YamlProfileLoader($locator)));
$delegatingLoader = new DelegatingLoader($loaderResolver);
foreach ($yamlProfileFiles as $yamlProfileFile) {
$profileName = basename($yamlProfileFile, '.yml');
$profiles[$profileName] = $delegatingLoader->load($yamlProfileFile);
}
So is the Yaml file it's parsing:
# profiles/germany.yml
locale: de_DE
hostname: %profiles.germany.host_name%
At the moment, the resulting array contains literally '%profiles.germany.host_name%' for the 'hostname' array key.
So, how can I parse the % parameters to get the actual parameter values?
I've been trawling through the Symfony 2 code and docs (and this SO question and can't find where this is done within the framework itself. I could probably write my own parameter parser - get the parameters from the kernel, search for the %foo% strings and look-up/replace... but if there's a component ready to be used, I prefer to use this.
To give a bit more background, why I can't just include it into the main config.yml: I want to be able to load app/config/profiles/*.yml, where * is the profile name, and I am using my own Loader to accomplish this. If there's a way to wildcard import config files, then that might also work for me.
Note: currently using 2.4 but just about ready to upgrade to 2.5 if that helps.
I've been trawling through the Symfony 2 code and docs (and this SO question and can't find where this is done within the framework itself.
Symfony's dependency injection component uses a compiler pass to resolve parameter references during the optimisation phase.
The Compiler gets the registered compiler passes from its PassConfig instance. This class configures a few compiler passes by default, which includes the ResolveParameterPlaceHoldersPass.
During container compilation, the ResolveParameterPlaceHoldersPass uses the Container's ParameterBag to resolve strings containing %parameters%. The compiler pass then sets that resolved value back into the container.
So, how can I parse the % parameters to get the actual parameter values?
You'd need access to the container in your ProfileLoader (or wherever you see fit). Using the container, you can recursively iterate over your parsed yaml config and pass values to the container's parameter bag to be resolved via the resolveValue() method.
Seems to me like perhaps a cleaner approach would be for you to implement this in your bundle configuration. That way your config will be validated against a defined structure, which can catch configuration errors early. See the docs on bundle configuration for more information (that link is for v2.7, but hopefully will apply to your version also).
I realise this is an old question, but I have spent quite a while figuring this out for my own projects, so I'm posting the answer here for future reference.
I tried a lot of options to resolve %parameter% to parameters.yml but no luck at all. All I can think of is parsing %parameter% and fetch it from container, no innovation yet.
On the other hand I don't have enough information about your environment to see the big picture but I just come up with another idea. It can be quite handy if you declare your profiles in your parameters.yml file and load it as an array in your controller or service via container.
app/config/parameters.yml
parameters:
profiles:
germany:
locale: de_DE
host_name: http://de.example.com
uk:
locale: en_EN
host_name: http://uk.example.com
turkey:
locale: tr_TR
host_name: http://tr.example.com
You can have all your profiles as an array in your controller.
<?php
namespace Acme\DemoBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class DefaultController extends Controller
{
public function indexAction()
{
$profiles = $this->container->getParameter('profiles');
var_dump($profiles);
return $this->render('AcmeDemoBundle:Default:index.html.twig');
}
}
With this approach
you don't have to code a custom YamlLoader
you don't have to worry about importing parameters into other yml files
you can have your profiles as an array anytime you have the $container in your hand
you don't have to load/cache profile files one by one
you don't have to find a wildcard file loading solution
If I got your question correctly, this approach can help you.
I'm currenly working on the project where i need something orther than bundle. Something i call "Module".
It should be different from the bundle in that when project is starting system doesn't know which "Modules" will be used
and how they will be configured.
Also i'm going to use these modules similar to bundles
$response = $this->forward('AcmeHelloModule:Hello:fancy');
OR
$response = $this->forward('Acme/Hello:Hello:fancy');
Here HelloController->fancyAction(); would be executed. And this controller described say in file /src/modules/Acme/Hello/Controller/HelloController.php
So the question is how to implement this ?
a solution would be to implement a PluginBundle that can dynamicly install, load and run your so called modules.
the PluginBundle would not contain specific plugin code at all, but the runtime environment for you modules/plugins. you may then save in the database which plugins/modules are enabled and load them dynamicly at runtime.
with this sollution it should be possible to create a dynamic plugin mechanism as in wordpress. modifying the AppKernel at runtime is not a good solution because you'd also have to clear the cache when en- disabeling bundles.
In AppKernel add the following method:
public function getBundle($name, $first = true)
{
if (substr($name, -6) == 'Module')) {
return $this->getBundle('ModuleBundle')->getModule($name, $first);
}
return parent::getBundle($name, $first);
}
and all the logic runs in ModuleBundle.
But make sure the type of response is the same as Kernel->getBundle();