How to protect files created/imported by composer? - php

I just installed composer to manage my project's dependencies.
But I end up with a problem: how to protect the files that composer created?
Shouldn't there be an .htaccess file at the root of vendor? (for my case at the root of the libsproduction folder)
Here is my composer.json file :
{
"config": {
"vendor-dir": "libsproduction/"
},
"require": {
"spipu/html2pdf": "^5.2",
"phpmailer/phpmailer": "^6.1",
"tinymce/tinymce": "^5.2",
}
}

Composer files (both the vendor directory and the composer.json and composer.lock files themselves) shouldn't be in a publicly accessible place.
But the way to do this is not to create an .htaccess or something similar under a webserver different from Apache. What you should do is serve a directory different than the one containing these directory and files. Nor changing the vendor name as you are doing.
The way this is generally done, by most (if not all) composer based frameworks, is to create a "public" or "web" directory which is the one you would configure your web server to actually serve, and put your application entry file(s) there.
E.g.
project-root-dir
├── public
│ └── index.php
├── vendor/
├── composer.json
├── composer.lock
The directory your web server should point to would be public in this scenario. So visiting users cannot directly see anything that's not within that directory.
To load composer's autoloader so that all packages classes are available, you simply do something like:
// public/index.php
require dirname( __DIR__ ) . '/vendor/autoload.php';
/* your application/script logic goes here /*
This way you can also put any other file that shouldn't be user accessible (configuration, logs, cache, etc) one level up from the publicly accessible directory, and you have work less to protect your sensitive files.

Related

Change vendor directory path for Symfony project

I'm working to create two symfony projects with one vendor directory
// I need to change this :
my-project1/
└─ vendor/
my-project2/
└─ vendor/
// To this :
vendor/
my-project1/
my-project2/
First of all, I would advise you not to do it (why do you want it anyway?), but answering the question: you have to set up vendor-dir in both projects to ../vendor.

How to get the root package path using composer

I'm developing a PHP component called php-app-config using composer.
This component, once required by another project, and installed using composer install, should look for config files inside the config folder of the root package, something like root_package/config/config.yml.
The ./config/config.yml should exists only in the root package and not inside the component imported by the "require:" in composer.json, as below:
▾ root-package/
▸ bin/
▸ build/
▾ config/
▸ locales/
config.yml
▸ src/
▸ tests/
▾ vendor/
▸ composer/
▸ phpdocumentor/
▸ phpspec/
▸ phpunit/
▾ robotdance/
▾ php-app-config/
▾ src/
Config.php -> how to get the root "config/config.yml" path from here?
▸ tests/
composer.json
composer.lock
phpunit.xml
README.md
The root package can be a web app or command line utility.
Is there any way to get the root package path using composer? If not, what is the better way?
Using ReflectionClass:
$reflection = new \ReflectionClass(\Composer\Autoload\ClassLoader::class);
$vendorDir = dirname(dirname($reflection->getFileName()));
You can use composer's very own \Composer\Factory::getComposerFile(); to get to the project root directory:
$projectRootPath = dirname(\Composer\Factory::getComposerFile());
And with your case, you can access your root-package/config/config.yml by:
$configYmlPath = $projectRootPath . '/config/config.yml'
Don't forget to add composer to your dependencies for the \Composer\Factory::class to be available:
$ composer require composer/composer
I would suggest "anchoring" your application (web or cli) by defining the root path as a constant.
When you have for instance a root-package/src/application.php file, it should know where it lives, something like define('APP_ROOT_FOLDER', dirname(__DIR__)); could help. Once the constant is declared, it's available for dependencies, too.
So, in /php-app-config/Config.php you would simply use the constant:
$config = APP_ROOT_FOLDER . '/config/config.yml';
(Or define a APP_CONFIG_ROOT_FOLDER constant which points directly to the config folder of the application.)
You could also try go some folder levels up from the dependency.
In php-app-config/Config.php you would use __DIR__, which is root-package/vendor/robotdance/php-app-config/src. Now, you would need to go 4 levels up to reach root-package/.
$config = __DIR__.'/../../../../config/config.yml';
This will not work out, when your application gets packaged as a PHAR.
Is there any way to get the root package path using Composer?
If you have the Composer object, you can get the path of the vendor directory from the Config object:
$vendorPath = $composer->getConfig()->get('vendor-dir');
then, go one folder up $config = dirname($vendorPath) . '/config/config.yml';

Editing phpci.yml File for my Project

I've installed PHPCI and have added a project named 'myproject' in PHPCI for testing. It is asked that I should include a 'phpci.yml' file in the root directory of the project. Here is how this 'phpci.tml' file should look like:
Click here to see the file pattern. Which part of this file should I edit to include it in my project as myproject's description as given below?
Project root direcotry: myproject
database name: mydb
database user: root
database pass: secret
host: localhost
Can some one please help me in this regard?
First you need to create phpci.yml file in your project's root directory, in your case it will be myproject/phpci.yml . This file contains configuration and usage of plugins. You might also need those plugins in your project for PHP-CI to test build. Use composer to to include those plugins in your project. To do that add another file in your project's root directory myproject/composer.json.
This happens when PHP-CI cannot find a plugin from its own directory, then it uses project's vendor directory to execute those plugins.
Example File/Config Format:
Suppose you have directory structure like this:
./myproject/
./myproject/protected/
./myproject/assets/
./myproject/protected/runtime/
and you want to run PHP-CI on ./myproject/protected/ while looking to skip ./myproject/assets/ & ./myproject/protected/runtime/ directories then your phpci.yml will look like this:
phpci.yml
build_settings:
ignore:
- "assets"
- "protected/runtime/"
setup:
composer:
action: "install"
test:
php_parallel_lint:
directory: "protected"
ignore:
- "assets"
- "protected/runtime"
php_code_sniffer:
path: "protected"
ignore:
- "assets"
- "protected/runtime"
standard: "code-sniffer-settings.xml"
allowed_errors: 10
allowed_warnings: 10
php_unit:
config:
- "protected/tests/phpunit.xml"
args: "--stderr"
path: "protected/tests/unit"
php_cpd:
allow_failures: true
path: "protected"
ignore:
- "assets"
- "protected/runtime"
php_docblock_checker:
allowed_warnings: -1
path: "protected"
ignore:
- "assets"
- "protected/runtime"
php_loc:
directory: "protected"
pdepend:
directory: "protected"
composer.json
{
"require-dev": {
"squizlabs/php_codesniffer": "2.*",
"sebastian/phpdcd": "*",
"phpmd/phpmd" : "#stable",
"phpunit/phpunit": "4.0.*",
"sebastian/phpcpd": "*",
"jakub-onderka/php-parallel-lint": "0.*",
"phpunit/php-code-coverage": "2.0.0",
"pdepend/pdepend": "2.2.2"
}
}
As to answer your question:
Which part of this file should I edit to include it in my project
Change test: section in phpci.yml and remove extra plugins that you don't want to be executed by PHP-CI, while leave composer section as it is, PHP-CI will run composer automatically on its own when testing a build.

Composer - Autoload and PSR-0 vs PSR-4

I'm beginning to study Composer and am developing a system where I separate the files core application files, as follows:
/root
|-- /src
|-- /App
|-- /DBConfig
|-- /Controller
|-- /Model
|-- /Core
|-- /Helper
|-- /Controller
|-- /Model
So, to set this setting in composer.json file and get access to all classes both /App much /Core would be this way?
"autoload" : {
"psr-X" : {
"App\\" : "/src",
"Core\\" : "/src"
}
}
Or is there a more correct way?
I have also read about PSR-0 vs PSR-4 and I am still somewhat in doubt which one to use. In my case what should I implement, PSR-0 or PSR-4?
You didn't need 2 entries just one for the main namespace so something like this for PSR-4:
"autoload" : {
"psr-4" : {
"MyApp\\" : "/src" }
}
As long as everything in src/ uses the same namespace that's all you'll need. Just let the autoloader do it's job.
As to which to use I'd go with PSR-4 because at some point it is expected that PSR-0 will be deprecated and as PSR-4 is made to be backwards compatible minus some warts for older legacy programs there isn't really a difference except of you start using some of it newer features

Ideal project directory structure for web application using Grunt with npm, bundler and composer

I've got a project set up for a web application using Grunt to automate build tasks. I'm using SASS and Compass as well as Composer to manage PHP dependencies. Currently I have a folder structure which looks like this:
-project
|-build
|-node_modules
|-src
| |-composer.json
|Gemfile
|Gruntfile.js
|package.json
This way all of my dependencies for Grunt are configured in package.json and managed by npm, the dependencies for SASS and Compass are configured in the Gemfile and managed by bundler and the dependencies for PHP are configured in composer.json and managed by Composer. Grunt copies over files from the src folder to build during a build, as well as generating/compressing CSS from SASS and minifying js.
I'm wondering if there's a better folder structure for dealing with this as I'd prefer to be able to run all the initial working environment setup from the project root, rather than having to run composer from within src. At the moment I'm keeping it in src in order to generate the autoload path correctly, otherwise it treats the project root as the web root.
Update:
Apologies for the unaccept and for the insufficient explanation. To help clarify below is the content of my composer.json now that it has been moved to the project root, the issue is not with vendor files but with using composer to create an autoloader for project files:
{
"config": {
"vendor-dir": "src/vendor"
},
"repositories": [
{
"type": "composer",
"url": "https://packages.zendframework.com/"
}
],
"require": {
"aws/aws-sdk-php": "2.4.*",
"zendframework/zend-json": "2.0.*"
},
"autoload": {
"psr-0": {"Project\\": "src/include/"}
}
}
Which outputs the following autoload_namespaces.php file inside vendor/composer
// autoload_namespaces.php #generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname(dirname($vendorDir));
return array(
'Zend\\Stdlib\\' => array($vendorDir . '/zendframework/zend-stdlib'),
'Zend\\Json\\' => array($vendorDir . '/zendframework/zend-json'),
'Symfony\\Component\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher'),
'Guzzle\\Tests' => array($vendorDir . '/guzzle/guzzle/tests'),
'Guzzle' => array($vendorDir . '/guzzle/guzzle/src'),
'Project\\' => array($baseDir . '/src/include'),
'Aws' => array($vendorDir . '/aws/aws-sdk-php/src'),
);
Having the $vendorDir look two levels up with the double dirname call is ok, but the $baseDir is now pointing to the level above src, which is now explicity hardcoded into the autoloader for Project. I suspect the only way to solve this is to move composer.json back into the src folder, or by writing a build script to rewrite this file, which seems nasty. Any alternatives?
You shouldn't be forced to put composer.json anywhere else than the project root, but your reason to do so is barely explained. How did you configure your autoloading? You could simply add src/ to the autoloading path and move composer one level up - and subsequently change the path to vendor/autoload.php to be one directory level deeper than now.
Update
Based on the new information, you do split your project up during deployment, and the contents of the original src folder is copied/morphed/moved to a build folder.
I'd suggest to run composer install on the final build folder before pushing the files live. That means you need to copy the composer.json and most importantly composer.lock files into that build folder, and for reasons of symmetry, these files should reside inside src like you started, and then also copied.

Categories