What's the proper way to work with assets in Yii? - php

I notice that Yii creates strange set of directories (names like 8523d23 or 10s89b92) in assets directory, and this even happens at runtime. For example, one of my tables got more than 10 records, pagination kicked-in and I got a new files in assets subdirectory named pager.css.
When I move my site from testing to production, should I copy all those, or just create an empty "assets" directory, and it will be filled at runtime?
If I want to add, for example, some new jQuery plugin, how should I proceed?
For example, I wish to add jquery.charcounter.js, do I copy it to assets or to yii/framework/web/js/source? If I do the latter, how do I get this .js file included in HTML page output?

assets should be a writable directory. Yii takes care of assets.
By calling Yii::app()->assetManager->publish() some stylesheets, images, scripts, or even entire directories can be put into a web-visible folder.
pager.css and other non-familiar files are produced by widgets (CLinkPager for example) and other components (such as CClientScript publishes jQuery whenever you need that).
During deployment, this folder should be empty, but it doesn't really matter.
Adding plugins should never be done through framework folders. You can place them either in components dir and publish it runtime if necessary, or into any other convenient visible directory (like as images or css).
Update
To embed jquery.charcounter.js, put it in components directory, then call
Yii::app()->clientScript->registerScriptFile(
Yii::app()->assetManager->publish(
Yii::getPathOfAlias('application.components').'/jquery.charcounter.js'
),
CClientScript::POS_END
);
Regarding weird folder names, I firmly believe they are unique hashes (or part of), so they can be differentiated if application uses several extensions.

This would resolve the query as this provides detailed explanation for the assets folder:
http://www.yiiframework.com/wiki/148/understanding-assets/

Related

Translate text in config folder cakephp 3

I'm trying to internationalize a CakePHP 3 application using cake i18n extract. All the texts coming from src folder are translated fine, but I have some text that I put inside config/bootstrap.php but those don't get translated even though I placed them inside the double underscore function __('My text') and I also generated the translation files in src/Locale folder (the same way I did for the other texts that work.
Any idea why my texts in config/bootstrap.php won't get translated?
Thanks in advance for any help
They do not show up because by default the extract task only looks in the src folder. When running the task it will ask you from what paths to extract, and it should only list the src folder by default.
You can either add your custom paths interactively in the shell when it asks you for the folders that should be looked up, or you can use the paths option to define them in beforehand, like:
bin/cake i18n extract --paths /var/www/app/config,/var/www/app/src
When doing so may also want to use the output option to specify the output path, as the task will use the first path as the root for output, ie with the above paths it would put the files in config/Locale instead of src/Locale. Alternatively you can switch the paths, but then the messages from the config folder files would appear at the bottom of the .pot file.
See also
Cookbook > Console Tools, Shells & Tasks > I18N Shell > Generating POT Files > Extracting from multiple folders at once
It depends on where you set the application locale with I18n::setLocale(). Your application using App.defaultLocale setting to determinate wich language sould be shown.
If you change your language in your controller, your configuration files already loaded so this will not effect on these files just on those files what will be loaded after your setLocale.
Try to change your language before translatable files loaded, or load translate configuration files in controller after changeing the appLocale.

Composer - how do to get root of project?

I'm trying to use the Composer autoloader located at vendor/autoload.php. However, I can't seem to figure out how to get to the root of the project, from which I could then navigate to vendor/autoload.php. I'm having to specify the relative path in each file (i.e. ../../../vendor/autoload.php). This seems like a very nasty way to get to the autoloader, since this path will be different depending on how deep the file is.
Is there a way to get to the root directory without specifying a relative path, or do I need to go up x parent directories in every file?
PHP has no way of knowing what the "root of the project" is. You could have any number of directories on your disk, with files called vendor/autoload.php in several of them, and only you know what's special about the "project root". So ultimately, the answer is no, there is no way.
However, note that you only need to include the autoloader in files which aren't themselves included or autoloaded. The autoloader is something you load once, as part of the configuration / bootstrapping of your code, and it then loads whatever classes it needs wherever they're referenced.
So the way to limit the mess of different levels is to structure your project carefully. For instance:
Route all requests via one or two "routers", such as a single "index.php" file. Use Apache mod_rewrite or the equivalent in Nginx etc to make all URLs actually load this script, and then in the script work out what code to run based on the URL. You can use libraries such as nikic/FastRoute to translate the URLs into functions to call, which will then be autoloaded.
Use different PHP files, but all in a reasonably flat directory structure, so that they all have to "climb" the same number of levels to reach the project root.
The same principle applies to use in command-line scripts or any other kind of application: limit or structure the "entry points", because only those need to know where to load the autoloader.
If you already have some kind of config file loaded on every request / script run / unit test / etc, it might be sensible to put the require_once 'vendor/autoload.php'; line in there. Like the configuration, the autoloader is "global state" that you want to just set up once and then forget about.

Bypass Symfony framework to display folder content

First of all. I haven't got any knowledge about Symfony. I just have to do a few modifications to an existing site quick and dirty. Now here is the case.
I need to "bypass" the Symfony framework to access static content in a folder e.g. (domain.com/folder).
This folder contains index.html and all the needed images, css, js etc. It also contains sub pages like (domain.com/folder/sub.html, domain.com/folder/sub2.html etc.). These sub pages are accessible thourgh domain.com/folder/index.html.
How can I do this?
SOLVED: (by user3749178)
Put you folder under /web. And a note for anyone else -> you also have to reference the file name.
domain.com/folder/ -> does not work
domain.com/folder/index.php -> works
Put you folder under /web. Everything what is in your /web directory is visible via http.

grouping and including files in a php project, by the book

I'm working on my first, rather big project in php. I decided to build everything from scratch, without any framework.
First I had the following structure:
index.php
includes/ //all php pages, except index.
includes/scripts/ //all php classes that do not print web pages.
styles/ //all my css files.
images/ //all images used on the website.
But this was giving me trouble when including files from within the various folders.
I have now changed it to:
index.php
the rest of my .php files
styles/
images/
All my includes are working properly now, without having to jump between folders. But I feel like I have lost overview on my project.
At the moment I'm a bit lost on how to do things. What is, by the book, the proper way to group my folders and to include my files?
EDIT: I would also like to see some tips on actually including the files. What are some techniques to include a file, no matter where include() is called? A specific example, according to my first structure.
There was a script in includes/scripts, login.php. login.php then included page.php (a simple page template) from includes/. page.php would include several parts of the template (header.php, footer.php). But I also had to call page.php from the files in include/.
This was giving me trouble, because the relative path would be different if page.php was called from includes/ or from includes/scripts/
Your problem was probably caused by relative paths.
This can be solved by using absolute paths eg.:
require_once("/var/www/clients/client05/web29/web/includes/scripts/myClass.php");
To make it easier you can also define constants in index.php (or any other file that will get included every time)
define("WEB_ROOT", "/var/www/clients/client05/web29/web/");
define("INCLUDES_DIR", WEB_ROOT . "includes/");
define("SCRIPTS_DIR", INCLUDES_DIR . "scripts/");
Files can then be easly included
require_once(SCRIPTS_DIR . "myClass.php");
require_once(INCLUDES_DIR . "acp.php");
A just straight forward suggestion:
index.php
app/
styles/
images/
All PHP code goes into app/ and can be further organized like you see fit, for example one directory for your templates, one to store third-party code and then your own library that you build for your application.
You should be able to move the app folder then anytime to any other location on disk, especially out of the document root.
This is most easily done with a so called front controller that is routing all request that are incomming to the application to the relevant code (technically this allows you to even have multiple applications side-by-side).
In the layout above, index.php plays that role. It's the entry-point to your application.
You should not think about mere files, but about strategies about how to interact with resources.
As PHP has nice object oriented support now, you may take advantage of namespaces, and organize your classes in folders, the way you like.
If you don't want to use a framework [thing I strongly advise you to do however, as it will make your app secure and more maintainable], you will find this article enlightening about how to organize your structure.
You can pick up some components like the symfony autoloader to load classes as you wish, then handle all the other resources [css, js, images] simply according to your filesystem organization.
My preferred organizational structure involves:
index.php and all other php pages in the root ("/")
/includes/ (directory for included template items like header, footer, analytics code, etc... anything frequently reused)
/includes/classes/ (for php classes)
/images/ (self explanitory; I also use several directories inside this based on the most sensible organization of my images)
/style/ (for css, with a "/style/fonts/" directory for font files)
/scripts/ (for js or similar)
/support/ (for any setup files I might be utilizing)

PHP directory structure confusion

I am attempting to create a website utilizing PHP as the driving power behind the gears. The idea behind the site (generally) requires that each user be presented with the option of creating their own profile (currently considering creating a directory for each user).
I have been doing considerable research in order to set this application up in the best means possible. But I am suffering from extreme confusion when it comes to creating the directory structure. I am considering downloading a framework assistant (CodeIgniter) which might assist me in the venture, but I'd rather get the opinions of others first.
Currently I have all of my files and content within my public_html folder, and I am aware that this is not the ideal set-up. But I'm not sure how to go about creating an alternative structure. I do not know where to store the various templates (header.php, footer.php, etc) and how/where to call them.
I want to create pages to list the "About", "Contact Page", and other content, but do not know where these pages should be located? Do I save the content of these pages within the public_html directory and simply include the templates from the various subfolders?
Concerning a config.php file: I am attempting to have all of the necessary information pertaining to MySQL connections within a single file, as well as other necessary information to be included at the beginning of EACH page within the site.
Thoughts? I'm fairly new to the cloud, and so simple and basic responses would be greatly appreciated!
You're thinking of this wrong. You don't need a directory for each user. You can use GET params to have one script (profile.php, for example) pull the appropriate profile for a user dependent on data passed to it. For example, profile.php?userid=5212 would pull the profile for user 5212 ($_GET['userid'] would contain the user's id in this case). Passing nothing could easily default to pulling the profile for the currently logged in user.
You could also use mod_rewrite so that http://www.yoursitehere.com/profile/5212/ could do the same thing (look into routes in most PHP frameworks)
Your directory structure should suit you. If the site is simple enough you could get away with something simple like just
public_html/
css/
includes/
images/
js/
Your database configuration could live in public_html/includes/ and you could include it on any page requiring a database connection. Your about and contact pages can be actual files located in public_html/ to keep things simple. Again, these are just suggestions. Your directory structure should be whatever you need it to be.
Store everything in a structure that makes sense to you. Something like this should work:
public_html
-Includes
-images
-css
-blog
And so on...
regarding the config file, you can store in in the public_html directory, or in the includes directory
You might consider using a PHP Web Framework like Symfony. It will help with a lot of the basics so that you can concentrate on the Product features.
For the user profile, Store all there information in a database with user id as a field.
When the user logs on, run a query to select all the information by querying against there user id.
As for file structure, you could use:
public html
includes
header.html
footer.html
config.php
classes
pages (stores other pages besides index.php here, contact, about etc.)
css
JS
index.php/html
and outside of the public_html folder I have my mysqli.php file.
To include these header files in your index.php file you would simply create (in your includes folder or wherever you choose) a config.php file with something like the following :
require_once($server['document_root']."/classes/filename.php"); // include needed files and mysqli connection here as well
You could also set a custom error handler in the config file as well if required.
In your index.php file you would then call the config file (which would automatically include any files you specified in the config file as well) and your header and footer i.e
include('/includes/header.html');
include('/includes/config.php');
<!--ENTER PAGE CONTENT HERE-->
include('/includes/footer.html');

Categories