Forgive the seeming lameness here. I'm working with a shared hosting with onnly access to cpanel and host are not willing to install composer nor PHPWord on my behalf. Is it possible to install PHPWord by just downloading the ZIP from github? Thanks
Yes, I do it all the time. For PHPWord, I would download the zip file from GitHub and move the contents of the src folder to a directory called "lib\PhpOffice\PhpWord". You'll then need a PHP class loader. I always use this for autoloading, provided the Classes are properly namespaced, which appears to be the case.
$GLOBALS['class_path'] = array(__DIR__ . '/lib', __DIR__);
// Set-up class_path superglobal variable using php include_path as basis
if (!array_key_exists('class_path', $GLOBALS)) {
$GLOBALS['class_path'] = array();
foreach (explode(PATH_SEPARATOR, get_include_path()) as $path) {
// substitute __DIR__ path for '.' instead
if ($path == '.') {
array_push( $GLOBALS['class_path'], realpath(__DIR__) );
continue;
}
array_push( $GLOBALS['class_path'], realpath($path) );
}
}
if (!function_exists('import')):
function import($package = '') {
if (empty($package)) {
trigger_error("Package path must be specified.", E_USER_ERROR);
}
$package_bits = explode('\\', $package);
$package_path = implode(DIRECTORY_SEPARATOR, $package_bits) . '.php';
foreach ($GLOBALS['class_path'] as $path) {
$file = $path . DIRECTORY_SEPARATOR . $package_path;
if (file_exists($file)) {
require_once($file);
$entity_name = implode('\\', $package_bits);
if (!(class_exists($entity_name, false) ||
interface_exists($entity_name, false)
|| trait_exists($entity_name, false))) {
$caller = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1)[0];
trigger_error("Entity '" . $package . "' not found in file '" . $package_path . "' for import called in " .
$caller['file'] . " on line " . $caller['line'], E_USER_ERROR);
}
return;
}
}
}
endif;
spl_autoload_register('import');
Set your $GLOBALS['class_path'] to the location of the 'lib' directory and be sure to use 'use' as needed before attempting to instantiate PHPWord.
Hope this helps!
You can use Composer locally and then upload the files to the server.
I asked about this here: Using Composer locally then uploading files through FTP
Basically, if you can't run Composer on the server, use it locally, then copy the necessary files to the server.
The reason you should use it is because it will download the dependencies for you, without you having to manually configure a load of stuff. That's very much the point of Composer :)
composer require phpoffice/phpword
Using version ^0.13.0 for phpoffice/phpword
./composer.json has been created
Loading composer repositories with package information
Updating dependencies (including require-dev)
- Installing pclzip/pclzip (2.8.2)
Downloading: 100%
- Installing phpoffice/common (v0.2.6)
Downloading: 100%
- Installing zendframework/zend-stdlib (2.4.13)
Downloading: 100%
- Installing zendframework/zend-validator (2.4.13)
Downloading: 100%
- Installing zendframework/zend-escaper (2.4.13)
Downloading: 100%
- Installing phpoffice/phpword (v0.13.0)
Downloading: 100%
Here you can download PHPWord without composer:
https://php-download.com/package/phpoffice/phpword
On this site are all libraries from the composer network but you can download all of them without a composer installation.
Download The PHpWord Zip FIle From Here: https://github.com/PHPOffice/PHPWord/archive/develop.zip
Source:: https://github.com/PHPOffice/PHPWord
PHPWord requires the following extension:
PHP 5.3.3+
XML Parser extension
Zend\Escaper component
Zend\Stdlib component
Zend\Validator component
Zip extension (optional, used to write OOXML and ODF)
GD extension (optional, used to add images)
XMLWriter extension (optional, used to write OOXML and ODF)
XSL extension (optional, used to apply XSL style sheet to template )
dompdf library (optional, used to write PDF)
Example Of basic usage of PHPWord library.
https://github.com/PHPOffice/PHPWord
Related
I'm writing unit tests for my Shopware Plugin. I've setup the same PHPUnit environment as SwagPayPal.
What I did:
composer.json
[...]
"require": {
"ext-json": "*",
"php": ">= 8.0",
"goetas-webservices/xsd2php-runtime": "^0.2.16",
"enqueue/stomp": "^0.10.16",
"shopware/core": "6.4.12.0"
},
"autoload": {
"psr-4": {
"Namespace\\Plugin\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Namespace\\Plugin\\Test\\": "tests/"
}
},
[...]
phpunit.xml.dist bootstrap="tests/TestBootstrap.php"
TestBootstrap.php is a 1:1 copy of the same file from SwagPayPal
except ->addActivePlugins('SwagCmsExtensions') was removed. https://github.com/shopwareLabs/SwagPayPal/blob/10694e851a11ac60e98cdb2130e66724611ef9a6/tests/TestBootstrap.php
My tests were all working fine. I now added the following code in one test:
$customerRepository = $this->getContainer()->get('customer.repository');
$customerRepository->upsert([$customerData], Context::createDefaultContext());
After calling upsert it crashes with Compile Error: Cannot declare class Shopware\Core\Checkout\Promotion\Cart\PromotionProcessor, because the name is already in use
I can get it working when I run sudo rm -rf var/cache/test_* but only once. When running it a second time it crashes again.
It seems it loads Shopware from the vendor folder of the plugin and then also from the root folder. I don't get why it's working the first time, but not a second time.
Edit: I checked all my namespace declarations in the PHP test files and I'm pretty sure they're correct. So I think it's another cause I can't find.
This is caused by the classes being autoloaded multiple times. It's hard to say what causes this without knowing all the code involved. Rather than copying from an existing plugin I'd suggest you start from scratch and follow the documentation on how to setup a clean environment for your tests.
I just updated my tests/TestBootstrap.php to fix my problem.
I removed the ->setClassLoader(require dirname(__DIR__) . '/vendor/autoload.php') call, so it doesn't load the composer generated stuff anymore.
I added the following code so it adds the PSR-4 namespace prefixes for my plugin:
$pluginComposerDir = realpath(__DIR__ . '/..');
$pluginComposerJson = json_decode(file_get_contents($pluginComposerDir . '/composer.json'));
foreach (['autoload', 'autoload-dev'] as $loader) {
if (is_object($pluginComposerJson->$loader) && is_object($pluginComposerJson->$loader->{'psr-4'})) {
foreach ($pluginComposerJson->$loader->{'psr-4'} as $namespace => $path) {
$classLoader->addPsr4($namespace, $pluginComposerDir . '/' . $path);
}
}
}
So now I have best of both worlds:
My plugin only adds the autoload-dev namespace(s) for tests.
It doesn't load the composer dependecies of my plugin, so I get no collisions with the Shopware root or other dependencies
I need to install my plugin dependencies in the Shopware root and if I don't do it Shopware won't install my extension and warn me about the failed dependencies:
Failed Dependency: Required plugin/package "goetas-webservices/xsd2php-runtime ^0.2.16" is missing or not installed and activated
Failed Dependency: Required plugin/package "enqueue/stomp ^0.10.16" is missing or not installed and activated
Full tests/TestBootstrap.php:
<?php declare(strict_types=1);
// based on tests/TestBootstrap.php of SwagPayPal
/*
* (c) shopware AG <info#shopware.com>
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Shopware\Core\TestBootstrapper;
if (is_readable(__DIR__ . '/../../../../vendor/shopware/platform/src/Core/TestBootstrapper.php')) {
// from Shopware root vendor dir
require __DIR__ . '/../../../../vendor/shopware/platform/src/Core/TestBootstrapper.php';
} elseif (is_readable(__DIR__ . '/../../../../vendor/shopware/core/TestBootstrapper.php')) {
// from Shopware root vendor dir
require __DIR__ . '/../../../../vendor/shopware/core/TestBootstrapper.php';
} else {
throw new Exception('TestBootstrapper not found. Please install Shopware root dependencies.');
}
$classLoader = (new TestBootstrapper())
->setProjectDir($_SERVER['PROJECT_ROOT'] ?? dirname(__DIR__, 4))
->setLoadEnvFile(true)
->setForceInstallPlugins(true)
->addCallingPlugin()
->bootstrap()
->getClassLoader();
$pluginComposerDir = realpath(__DIR__ . '/..');
$pluginComposerJson = json_decode(file_get_contents($pluginComposerDir . '/composer.json'));
foreach (['autoload', 'autoload-dev'] as $loader) {
if (is_object($pluginComposerJson->$loader) && is_object($pluginComposerJson->$loader->{'psr-4'})) {
foreach ($pluginComposerJson->$loader->{'psr-4'} as $namespace => $path) {
$classLoader->addPsr4($namespace, $pluginComposerDir . '/' . $path);
}
}
}
return $classLoader;
Edit: adjusted tests/TestBootstrap.php to load TestBootrapper class from Shopware root.
Summary:
I'm a web and backend newb, but basically I've inherited a CakePHP project and I'm trying to set up a dev environment. I'm trying to display my project-level src directory at http://localhost/backend/, which autoroutes to http://localhost/backend/admin/users/dashboard, but it only loads PROJECT_ROOT/vendor/maiconpinto/cakephp-adminlte-theme/src.
Question:
How do I load my own sidebar using my top-level src directory? Thanks in advance!
Here's the desired sidebar: correct myteamconnector sidebar
Here's the sidebar that is getting loaded: incorrect vendor files sidebar
Setup Info:
System: Mac OS 10.14
Dev Apps:
AMPPS v3.8
Apache v2.4.27
PHP v7.1
MySQL v5.6.37
CakePHP v3.5.17
PROJECT_ROOT/index.php:
require 'webroot' . DIRECTORY_SEPARATOR . 'index.php';
PROJECT_ROOT/webroot/index.php:
// Check platform requirements
require dirname(__DIR__) . '/config/requirements.php';
// For built-in server
if (php_sapi_name() === 'cli-server') {
$_SERVER['PHP_SELF'] = '/' . basename(__FILE__);
$url = parse_url(urldecode($_SERVER['REQUEST_URI']));
$file = __DIR__ . $url['path'];
if (strpos($url['path'], '..') === false && strpos($url['path'], '.') !== false && is_file($file)) {
return false;
}
}
require dirname(__DIR__) . '/vendor/autoload.php';
use App\Application;
use Cake\Http\Server;
// Bind your application to the server.
$server = new Server(new Application(dirname(__DIR__) . '/config'));
// Run the request/response through the application and emit the response.
$server->emit($server->run());
SOLVED
The issue was that the composer.json file was specifying "maiconpinto/cakephp-adminlte-theme": "^1.0" and therefore installing v1.1.0 which requires different implementations depending on the cakephp version being < or >=3.5.
So specifying "maiconpinto/cakephp-adminlte-theme": "1.0.8" in the composer.json file installed the previous version, which is compatible with the implementation in my repo.
For some reason in the working version there was a mismatch between the composer.json file and the vendor folder (i.e. the vendor folder contained a bunch of plugins that the composer.json file didn't have) allowing everything to work as long as you didn't run composer update, which my coworker hadn't done.
I had problems loading package I have required via composer
composer require package
PHP (version 5.6) said it did not recognised this package.
When looking into the scripts, I found in autoload_real.php these lines:
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION');
if ($useStaticLoader) {
require_once __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInitb5ab90658915f56241dbbea020198264::getInitializer($loader));
} else {
$map = require __DIR__ . '/autoload_namespaces.php';
foreach ($map as $namespace => $path) {
$loader->set($namespace, $path);
}
$map = require __DIR__ . '/autoload_psr4.php';
echo "<br>";
var_dump($map);
foreach ($map as $namespace => $path) {
$loader->setPsr4($namespace, $path);
}
$classMap = require __DIR__ . '/autoload_classmap.php';
if ($classMap) {
$loader->addClassMap($classMap);
}
}
My packages are listed inside the autoload_psr4.php file and are returned in the packages array but the code is going in to the if clause ($useStaticLoader is true) and in the autoload_static.php my package is not listed.
When setting $useStaticLoader to false, the else clause is loading my package as expected.
I'll add that the package I'm installing declare itself as a psr4 package.
What is the static flag mean and how can I make my package be listed in the autoload_static.php array?
Allow optionally disabling the static autoloader
The static autoloader presents a problem for environments where
pre-PHP
5.6 syntax compatibility is required. Many projects have automated CI that runs a linter across all files in the repository to prevent
developers from accidentally introdcing incompatible syntax. And while
the static autoloader properly guards itself on lower PHP versions, it
will still trip up linters. Given the number of bugs filed about this,
it appears to be a common setup: #5255, #5316, #5324, and #5407.
This adds a --no-static option to the dump-autoload command, which
will disable the static autoloader by updating autoload_real.php to
not look for the file, and removes autoload_static.php if it exists.
Also you can avoid this using --optimize-autoloader flag with install / update.
P.S.: I had the same problems with php 5.6 too, check your path and namespaces twice!
I am trying to install phpwkhtmltopdf on shared server (webhotel). The server has already composer installed, and I have SSH to server. But I am not too familiar with composer so I might be doing someting very basic wrong here..
So, I have downloaded the zip file from:
https://github.com/mikehaertl/phpwkhtmltopdf
and extracted the files on it to server to directory named as phpwkhtmltopdf.
Then, opening SSH cd-ing to that dir and running composer require mikehaertl/phpwkhtmltopdf but I only get question marks to beginning of line.
For the question marks I read that it could be a problem of detect unicode, so I placed to htaccess: php_flag detect_unicode Off and it seems that it is Off now locally.
But there is still the question marks and php wkhtmltopdf does not get installed. How to get it installed?
The problem is that you are fetching the package mikehaertl/phpwkhtmltopdf two times:
firstly, you fetched the zip and extracted it (manual installation).
then, you ran Composer to require it (installation via Composer).
Please decide how you want to install the package!
When you want to install the package with Composer, you just need to run composer require mikehaertl/phpwkhtmltopdf in a clean project folder.
Composer will then fetch the package and place it into the /vendor folder.
That's it.
Now, in order to use it you need two things:
you need to include Composers Autoloader during the bootstrap of your project. This enables that the Autoloader will load the library, when you access one the package/library classes.
// Register Composer Autoloader
define('VENDOR_DIR', __DIR__ . '\vendor' . DS);
if (!is_file(VENDOR_DIR . 'autoload.php')) {
throw new \RuntimeException(
'[Error] Bootstrap: Could not find "vendor/autoload.php".' . PHP_EOL .
'Did you forget to run "composer install --dev"?' . PHP_EOL
);
}
require VENDOR_DIR . 'autoload.php';
Well, finally, you need to code something using the library:
use mikehaertl\wkhtmlto\Pdf;
$pdf = new Pdf('/path/to/page.html');
if (!$pdf->saveAs('/path/to/page.pdf')) {
echo $pdf->getError();
}
Uhm, and you need the wkhtmltopdf binary... but i guess thats not the problem.
These are my steps:
i downloaded wkhtmltopdf http://download.gna.org/wkhtmltopdf/0.12/0.12.3.2/wkhtmltox-0.12.3.2_msvc2013-win64.exe
and installed it into c:\program files\wkhtmltopdf
now the executable resides in c:\program files\wkhtmltopdf\bin
i created the folder pdf-test
i ran the command composer require mikehaertl/phpwkhtmltopdf on the CLI
i created a file makepdf.php with the following content:
/**
* Register Composer Autloader
*/
define('VENDOR_DIR', __DIR__ . '\vendor' . DIRECTORY_SEPARATOR);
if (!is_file(VENDOR_DIR . 'autoload.php')) {
throw new \RuntimeException(
'[Error] Bootstrap: Could not find "vendor/autoload.php".' . PHP_EOL .
'Did you forget to run "composer install --dev"?' . PHP_EOL
);
}
require VENDOR_DIR . 'autoload.php';
/**
* Use library
*/
use mikehaertl\wkhtmlto\Pdf;
$pdf = new Pdf(array(
'binary' => 'C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe',
'ignoreWarnings' => true,
'commandOptions' => array(
'procEnv' => array(
// Check the output of 'locale' on your system to find supported languages
'LANG' => 'en_US.utf-8',
),
'escapeArgs' => false,
'procOptions' => array(
// This will bypass the cmd.exe which seems to be recommended on Windows
'bypass_shell' => true,
// Also worth a try if you get unexplainable errors
'suppress_errors' => true,
),
),
));
$pdf->addPage('<html>
<head>
</head>
<body>
<div id="print-area">
<div id="header">
This is an example header.
</div>
<div id="content">
<h1>Demo</h1>
<p>This is example content</p>
</div>
<div id="footer">
This is an example footer.
</div>
</div>
</body>
</html>');
if (!$pdf->saveAs('page.pdf')) {
echo $pdf->getError();
}
then i ran php makepdf.php
finally, the file page.pdf was generated
And that's it... :)
I've added composer to an existing project that uses the PHP autoload function. Now that composer autoload.php is being used I've removed my old autoload function and I'm trying to load my existing source directory via composer autoload but it isn't picking up any of my existing source classes.
Everything installed by composer loads fine and can be accessed via namespaces etc. so it's just the existing sources in the source directory not being picked up. Any suggestions?
I've looked at a few other of the composer questions on stackoverflow but nothing I've read has solved my problem.
File structure:
index.php
root/
sources/
vendor/
composer.json
media/
Composer autoload:
"autoload": {
"psr-0": {
"" : "sources/"
}
}
There were two things causing issues for me, one was the class file names and the second was a composer command that needed to be run.
My class file names were in the format {classname}.class.php when they need to be in the format that PSR-0 expects which is Classname.php (uppercase first letter) and in turn the classname in the class file follows the file name.
class Classname
{
...
The second issue was that I needed to run the below command.
composer dump-autoload
From composer.org:
If you need to update the autoloader because of new classes in a classmap package for example, you can use "dump-autoload" to do that without having to go through an install or update.
If your code structure is too complex to convert to PSR-* structure, you can use your old autoloader and composer autoload together.
spl_autoload_register( function ( $class ) {
$file = "sources/" . $class . ".class.php";
if ( file_exists( $file ) ) {
require $file;
return;
}
} );
require "vendor/autoload.php";