How to use composer/composer PHP classes to update individual packages - php

I want to use the composer/composer PHP classes to update individual plugin packages.
I do not want to use command-line solutions like exec("php composer.phar update");
I am unable to get it to work. I have tried several different options, much alike the following code.
It just returns a blank screen.
use Composer\Console\Application;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\BufferedOutput;
$input = new ArrayInput(array('command' => 'require vendor/packkage dev-master'));
$output = new BufferedOutput();
$application = new Application();
$application->run($input, $output);
dd($output->fetch());
Things i would like to achieve:
Download/Update individual packages
Get result output to verify success
Dump autoload
Remove/require packages
A bit of context details:
I am creating a plugin updater for my PHP application (in admin panel).
Every plugin is a composer package and resides on my own Satis repository.
The plugins get installed into a custom dir using my composer plugin.
I can read composer.lock locally and packages.json on the satis server to figure out
what packages require updates.
update
I've managed to at least get it to work. The no-output issue was due to $application->setAutoExit that needed to be false before running. Next issue that i had was that the required package would download itself into the same directory as the class where i called it from. Solved that by using putenv and chdir. Result:
root/comp.php
putenv('COMPOSER_HOME=' . __DIR__ . '/vendor/bin/composer');
chdir(__DIR__);
root/workbench/sumvend/sumpack/src/PackageManager.php
include(base_path() . '/comp.php');
$input = new ArrayInput(array('command' => 'require', 'packages' => ['vend/pak dev-master']));
$output = new BufferedOutput();
$application = new Application();
$application->setAutoExit(false);
$application->run($input, $output); //, $output);
dd($output->fetch());
This works, but it's far from ideal.

The full solution to this would be pretty long winded, but I will try to get you on the right track.
php composer.phar require composer/composer dev-master
You can load the source of composer into your project vendors. You might have already done this.
The code you are looking for is at: Composer\Command\RequireCommand.
$install = Installer::create($io, $composer);
$install
->setVerbose($input->getOption('verbose'))
->setPreferSource($input->getOption('prefer-source'))
->setPreferDist($input->getOption('prefer-dist'))
->setDevMode($updateDevMode)
->setUpdate(true)
->setUpdateWhitelist(array_keys($requirements))
->setWhitelistDependencies($input->getOption('update-with-dependencies'));
;
$status = $install->run();
Most of the command relates to the reading and writing to of the composer.json file.
However the installer itself is independent of where the configuration actually came from. You could in theory store the configuration in a database.
This is the static create method for the installer:
public static function create(IOInterface $io, Composer $composer)
{
return new static(
$io,
$composer->getConfig(),
$composer->getPackage(),
$composer->getDownloadManager(),
$composer->getRepositoryManager(),
$composer->getLocker(),
$composer->getInstallationManager(),
$composer->getEventDispatcher(),
$composer->getAutoloadGenerator()
);
}
You will need to pay special attention to the Package, And implement your own.
Although your current attempt to run it on the command line will work, I do not recommend it because Composer is primarily a development and deployment utility, not an application utility.
In order to smoothly use it to assist with loading plugins on a production environment, you will need to tightly integrate its internals with your own application, not just use it on the side.
This is something I am interested in as well, and I think this has inspired me to look into it myself. So I'll let you know what I come up with, but this is the best I can advise you for now on what I consider to be the correct approach.

Related

Run composer accross a broswser with a PHP

This post is in relation with this :
Run composer with a PHP script in browser
My problem is to solve how to install a library without terminal and take in consideration some hosting do not accept the exec command.
In summary the user can just click on the button to install apps with the library
Thank you.
I tried 2 solutions :
use Composer\Console\Application;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\StreamOutput;
putenv('COMPOSER_HOME=' . self::$root); // /www/mywebsite/shop/
putenv('COMPOSER_CACHE_DIR=' . CORE::BASE_DIRECTORY . '/Work/Cache/Composer/');
putenv('COMPOSER_HTACCESS_PROTECT=0');
first with this code
$stream = fopen('php://temp', 'w+');
$output = new StreamOutput($stream);
$application = new Application();
$application->setAutoExit(false);
$code = $application->run(new ArrayInput(array('command' => 'install tinify/tinify')), $output);
$result = stream_get_contents($stream);
var_dump($code);
var_dump($result);
The result is : (not work and nothing is installed)
int(1) string(0) ""
The second approach :
$input = new ArrayInput(array('command' => 'install tinify/tinify'));
$application = new Application();
$application->setAutoExit(false); // prevent `$application->run` method from exitting the script
$result = $application->run($input);
var_dump($result);
The result is : (not work and nothing is installed)
int(1)
You do not need to run composer on the production server.
You can run composer in a project on a computer with similar software (OS, php version). Then you can copy already built project directory with vendor folder in it to the production server.
Usually you can zip/gzip it first then transfer then unzip/ungzip. For the follow up updates something like rsync may be a fast solution for updating only those parts of project folder that changed.
You may want to have a script that copies your development directory first then cleans up any personal credentials (e.g. passwords to any SaaS solutions you use for development), and then does the composer & transfer automatically.

How to use this QR code library (php-qrcode-detector-decoder)

Please tell me step by step, I'm amateur on php.
visit here
How to use this code.
Please help or guide me to make this code work 100%.
require __DIR__ . "/vendor/autoload.php";
$qrcode = new QrReader('path/to_image');
$text = $qrcode->text(); //return decoded text from QR Code`
QR code decoder / reader for PHP
This is a PHP library to detect and decode QR-codes.
This is first and only QR code reader that works without extensions.
Ported from ZXing library
Installation
The recommended method of installing this library is via Composer.
Run the following command from your project root:
$ composer require khanamiryan/qrcode-detector-decoder
Usage
require __DIR__ . "/vendor/autoload.php";
$qrcode = new QrReader('path/to_image');
$text = $qrcode->text(); //return decoded text from QR Code
I'm making this an answer because it is too complex for a comment.
First of all you should really try to use this code before asking for help. But let's look at the proposed code anyway:
<?php
// This line calls the autoload script generated by Composer. This ensures that you can
// just use the library classes without having to manually include their specific files
require __DIR__ . "/vendor/autoload.php";
// This instantiates the QrReader class and points it to the path of a QR code image
$qrcode = new QrReader('path/to_image');
// This calls the text method on the above instance to determine the contents of the qr code
$text = $qrcode->text();
if this doesn't work for you then you should post the error(s) you got. If you can't see any errors then add the following right below the <?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
I had a lot of trouble to get this working library without composer too.
The thing is it works on windows but not on linux because of the wrong capitalization of filenames and directories and such.
Then I found this blog that has a great solution:
https://www.mgcwebsites.co.uk/solved-class-zxinggdluminancesource-not-found/
Install a version before Composer support was added
Perhaps you use shared hosting that doesn’t allow you to install Composer or use SSH. Perhaps, like me, your server works perfectly and you want to keep it as clean as possible. Either way checking through the commits I was pleased to see Composer support is a fairly recent addition and that by downloading the last commit before Composer support was added I was able to forget about Composer and get the library working in seconds.
https://github.com/khanamiryan/php-qrcode-detector-decoder/tree/cda63b7f4a8cd84d72c41b25c74284b56dc7f2cc
It works very well now...

Installing PHP library for Supervisor using composer

I want to use Supervisor to manager my processes. I have got it installed on my Amazon linux Machine and the basic setup runs fine as per the config file.
Now, I want to change the processes dynamically. Since it needs the config file to be changed every time and a restart, using PHP library to do the same seems to be a good option.
Specifically I am going through SupervisorPHP config to change the configuration dynamically and SupervisorPHP to manager Supervisor through PHP.
Following the README for SupervisorPHP config, I got it installed via composer
composer require supervisorphp/configuration
I copied the sample code
<?php
use Supervisor\Configuration\Configuration;
use Supervisor\Configuration\Section\Supervisord;
use Supervisor\Configuration\Section\Program;
use Indigophp\Ini\Rendere;
$config = new Configuration;
$renderer = new Renderer;
$section = new Supervisord(['identifier' => 'supervisor']);
$config->addSection($section);
$section = new Program('test', ['command' => 'cat']);
$config->addSection($section);
echo $renderer->render($config->toArray());
When I run this code, I get the following error:
PHP Fatal error: Class 'Supervisor\Configuration\Configuration' not found in test.php on line 7
I also tried to clone the repo and include the files individually, however it shows error for other dependencies. It would be great if I could use this.
There are 2 mistakes in the above code.
The first mistake is that you do not use the autoloader provided by composer so that php can find the necessary classes. To do so just add require __DIR__ . '/vendor/autoload.php'; (If the vendor folder is in a different path relative to the sample script then adjust accordingly).
The second mistake is in the use statement for Indigophp. Apart from the obvious typo in the word Renderer, if you check the source of Indigo you will see that it must be use Indigo\Ini\Renderer;
So the correct code to test your installation is:
<?php
require __DIR__ . '/vendor/autoload.php';
use Supervisor\Configuration\Configuration;
use Supervisor\Configuration\Section\Supervisord;
use Supervisor\Configuration\Section\Program;
use Indigo\Ini\Renderer;
$config = new Configuration;
$renderer = new Renderer;
$section = new Supervisord(['identifier' => 'supervisor']);
$config->addSection($section);
$section = new Program('test', ['command' => 'cat']);
$config->addSection($section);
echo $renderer->render($config->toArray());
Running the above code, you should get the following output:
[supervisord]
identifier = supervisor
[program:test]
command = cat

Include ZEND framework 2.3 in application without skeleton

There is a lot on the web about including ZEND, but I still don't get how to simply use it (without a skeleton) (In this case I only want to use Zend\Dom\Query)
I would like to:
1) Simply include the complete ZEND 2.3 library in a single application
or
2) Include a single ZEND 2.3 module
I'm using NGINX, but actually I just want to include it via PHP. Any hints, tips and or links?
What I did was:
include('./library/Zend/Dom/Query.php');
$c = curl_init($u);
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
$html = curl_exec($c);
$dom = new Zend\Dom\Query($html);
$results = $dom->execute('.foo .bar a');
...
Error is:
Fatal error: Class 'Zend_Dom_Query' not found in /SOMEDIR/myfile.php on line 12
Zend Dom and all of other Zend Framework 2 components developed independently from the framework's itself. All of them maintained separately and there are custom repositories exists for this components, respectively.
I think that the best way of using this components without framework's itself, using composer. We're living in open-source era and the year is 2014. All you need is making a search on packagist instead of trying to use Zend Dom (or any 3rd party library) via manually including/requiring into the codebase. Please use composer and follow the PSR standards.
To integrate the composer into your very own application, open the console and simply type:
cd /path/to/your/project
php -r "readfile('https://getcomposer.org/installer');" | php
After installation, use this command to add zend-dom dependency in your project:
php composer.php require zendframework/zend-dom:2.3.*
Now anywhere in your code, you can type new Zend\Dom\Query() to create a new dom query instance. (I'm assuming that you already read the autoloading process)
A simple way to include it via PHP is :
1. Make sure that the Zend directory is on your php include_path. Assuming Zend directory is in the library folder you'll have something like this in your index.php file:
$path= array();
$path[] = '.';
$path[] = './../library';
$path[] = get_include_path();
$path= implode(PATH_SEPARATOR,$path);
set_include_path($path);
2. Now just include Zend/Loader/StandardAutoloader.php first and then use it to load other classes. You can do this :
require_once 'Zend/Loader/StandardAutoloader.php';
$autoloader = new Zend\Loader\StandardAutoloader(array(
'fallback_autoloader' => true,
));
$autoloader->register();
With the $autoloader->register(), you don't need to include files each time you want to call classes. You have just to instanciate your classes :
$dom = new Zend\Dom\Query($html);

How reload Twig cache in Symfony 2

I have a application which is developed in PHP using the Symfony 2 framework. I have changed a HTML file, but the change is not reflecting when I refresh the page.
I restarted the server. No luck.
I tried to remove the Twig folder from the /protected/cache/ page itself. This is not loading.
How can I reload the Twig cache?
Notes:
I am using tomcat server to deploy.
I don’t have the Symfony 2 command line configured on the server.
I am new to PHP.
The most simple way, type the command :
rm -rf app/cache/*
The point is: all files in app/cache/ can be removed freely, they are regenerated when needed.
If you really want to clear only twig cache :
rm -rf app/cache/<environment>/twig
Replace <environment> by dev, prod, or test according to your requirements.
When creating a new Twig_Environment instance, you can pass an array of options as the constructor second argument. One of them is auto_reload. When developing with Twig, it's useful to recompile the template whenever the source code changes. If you don't provide a value for the auto_reload option, it will be determined automatically based on the debug value.
Set auto_reload to be true:
$twig = new Twig_Environment($loader, array('auto_reload' => true));
Twig's documentation for developers:
http://twig.sensiolabs.org/doc/api.html#environment-options
I had a similar problem, but deleting the cache-folder did not have any impact on my template and I don't know why. What seems to solve my problem now is the following code in my config_dev.yml:
twig:
cache: false
Maybe this is also a solution for you, so that you don't need to use the command all the time.
References:
TwigBundle Configuration
Twig Environment Options
If you are using opcache/other similar caching, deleting twig's cache folder won't refresh templates as twig cache consist of only .php files.
You need to delete twig's cache folder + execute php file which contains:
opcache_reset();
You have to do some changes in app.php file located in web folder.
Change:
$kernel = new AppKernel('prod', false);
to:
$kernel = new AppKernel('prod', true);
and clear the cache if you want.
You can use the Symfony console to clear cache
./bin/console cache:clear
you can add a function like this :
public function renderView($view, array $parameters = array())
{
$loader = new \Twig_Loader_Filesystem($this->container->getParameter("template_path"));
$twig = new \Twig_Environment($loader, array('auto_reload' => true,
'cache' => false
));
/////////////////////add a translate filter///////////////////////
$getTextdomain = new \Twig_SimpleFilter('trans',function ($string){
return $this->container->get('translator')->trans($string);
});
$twig->addFilter($getTextdomain);
//////////////////////////////////////////////////////////////////
///////////////////////////Add an extension twig//////////////////
$twig->addExtension(new Extension());
//////////////////////////////////////////////////////////////////
return $twig->render($view, $parameters);
}
If you are using OPcache make sure to comment out opcache.validate_timestamps=0 in dev environment.

Categories