I'm having significant amount of troubles trying figure out how to install and use DOMPDF with Composer and Symfony. It is a project written a few years ago and I am completely new to Composer, Symfony and DOMPDF...somebody else told me we were using Composer and Symfony.
I've installed DOMPDF using the puTTy command line interface by:
1. going to the folder where my composer.json is (vendor)
2. running the command "Install dompdf/dompdf" It completed successfully with no errors.
3. Then running the command composer "require dompdf/dompdf" which also completed successfully with no errors.
Then I get lost/confused...
I see instructions that say to edit composer.json with :
{
"require": {
"squizlabs/php_codesniffer": "2.0.*",
}
So here is the new contents of composer.json
{
"require": {
"spipu/html2pdf": "^5.0",
"dompdf/dompdf": "^0.8.1"
}
I've tried using DOMPDF by putting the following line in my PHP code and all I get is a blank page
use Dompdf\Dompdf;
There is also an autoload.php which looks like this:
//autoload.php #generated by Composer
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInit********************************::getLoader();
Following the rabbit hole, autoload_real.php looks like this:
// autoload_real.php #generated by Composer
class ComposerAutoloaderInit987ec9019a1b2f978bf00ce76684ede0
private static $loader;
public static function loadClassLoader($class)
{
if ('Composer\Autoload\ClassLoader' === $class) {
require __DIR__ . '/ClassLoader.php';
}
}
public static function getLoader()
{
if (null !== self::$loader) {
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInit987ec9019a1b2f978bf00ce76684ede0', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array('ComposerAutoloaderInit987ec9019a1b2f978bf00ce76684ede0', 'loadClassLoader'));
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
if ($useStaticLoader) {
require_once __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit987ec9019a1b2f978bf00ce76684ede0::getInitializer($loader));
} else {
$map = require __DIR__ . '/autoload_namespaces.php';
foreach ($map as $namespace => $path) {
$loader->set($namespace, $path);
}
$map = require __DIR__ . '/autoload_psr4.php';
foreach ($map as $namespace => $path) {
$loader->setPsr4($namespace, $path);
}
$classMap = require __DIR__ . '/autoload_classmap.php';
if ($classMap) {
$loader->addClassMap($classMap);
}
}
$loader->register(true);
if ($useStaticLoader) {
$includeFiles = Composer\Autoload\ComposerStaticInit987ec9019a1b2f978bf00ce76684ede0::$files;
} else {
$includeFiles = require __DIR__ . '/autoload_files.php';
}
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequire987ec9019a1b2f978bf00ce76684ede0($fileIdentifier, $file);
}
return $loader;
}}function composerRequire987ec9019a1b2f978bf00ce76684ede0($fileIdentifier, $file){if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
require $file;$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;}}
Additionally, I have 14 folders in the vendor file, which I assume are all packages used with Composer, but I don't see them being required in the composer.json file, and, after installing DOMPDF, I don't see a vendor folder for it. I'd like to remove them, but I don't know what is and is not being used.
I've read the "getting started guides" and I still don't know what I've done wrong.
I'm sure I will have a thousand more questions...thank you for your patience.
a) your composer.json file should be in the root of your project directory and not in the vendor directory.
b) just typing the command
composer require dompdf/dompdf
in your project directory should be enough to install the libraries in the vendor directory AND to add the line
"dompdf/dompdf": "^0.8.1"
in your composer.json.
c) Follow instructions on https://github.com/dompdf/dompdf how to use dompdf.
d) In general when working with composer you have to include the vendor/autoload.php file but in the Symfony framework that will already happen in the app/autoload.php.
require 'vendor/autoload.php';
e) dompdf does use namespaces. Little example:
require "../vendor/autoload.php"; // change path if you need to
use Dompdf\Dompdf;
// instantiate and use the dompdf class
$dompdf = new Dompdf();
$dompdf->loadHtml('hello world');
// (Optional) Setup the paper size and orientation
$dompdf->setPaper('A4', 'landscape');
// Render the HTML as PDF
$dompdf->render();
// Output the generated PDF to Browser
$dompdf->stream();
f) Lot of packages that can be installed with composer use other packages too. If you take a look at the composer.json from dompdf you will see that it requires some other packages which composer will automaticly install for you.
[edit]
Your composer.json is in the root directory of your project. Same for your vendor directory. In your vendor directory there will be a composer directory, that is normal. But execute any commands from your root directory. structure:
- [project root] (execute commands here)
|
|- composer.json
|- [vendor]
|
|- [composer]
If you got stuck just delete the whole vendor directory and composer.json file and again use the command
composer require dompdf/dompdf
Is there any function that would return the full path of my plugin in WordPress?
Example is
path/wp-contents/plugins/myplugin
I have tried plugin_dir_path(__FILE__) but returns the current dir.
I would suggest to use a WordPress internal constant to solve this case:
$my_plugin = WP_PLUGIN_DIR . '/my-plugin';
if ( is_dir( $my_plugin ) ) {
// plugin directory found!
}
Alternative
The other valid alternative is to compute the path from the URL which is more complex/confusing. I would not use this code:
$plugins_url = plugins_url();
$base_url = get_option( 'siteurl' );
$plugins_dir = str_replace( $base_url, ABSPATH, $plugins_url );
// Now $plugins_dir is same as the WP_PLUGIN_DIR constant.
$my_plugin = $plugins_dir . '/my-plugin';
My opinion in this case is: Use the constant WP_PLUGIN_DIR
Yeah as per description of plugin_dir_path it will give you current plugin file path. But as per what you asking here you can do something like below unfortunately no direct way,
$plugin_dir = ABSPATH . 'wp-content/plugins/plugin-folder/';
Edit: 18-09-2021
The best practice is to use with latest version is WP_PLUGIN_DIR as follow:
$plugin_dir = WP_PLUGIN_DIR . '/plugin-folder';
Code For Plugin Root Path
$dir = plugin_dir_path( __FILE__ );
// Example: /home/user/var/www/wordpress/wp-content/plugins/my-plugin/
Code for plugin path
echo WP_PLUGIN_DIR.'/plugin-name';
plugins_dir_path() is a misnomer.
It will always return the path to the current file.
Link to the codex:
https://developer.wordpress.org/reference/functions/plugin_dir_path/#more-information
It is a wrapper for trailingslashit( dirname( $file ) );.
The “plugin” part of the name is misleading – it can be used for any file, and will not return the directory of a plugin unless you call it within a file in the plugin’s base directory.
It is actually synonym for the trailingslashit() function.
IF the current file is in the plugins directory, then yes, the function returns the path of the current file.
However, if you call this function from a file inside any other directory, then current file is not in the plugins directory, and thus it will does NOT return the path to the plugins directory. It does always return the path to the current file, but without a trailing slash.
Most of the answers here are incorrect, or are only "sometimes" correct. Those answers will only work as they say IF your file happens to already be located in the plugins directory! In all other cases they will give you a misleading result: the path to your current file.
It is more likely that your file is in a *subdirectory *of the plugins folder.
If this is the case, this codex shows you how to create a URL to the current file:
https://codex.wordpress.org/Function_Reference/plugins_url
If you are using the plugins_url() function in a file that is nested inside a subdirectory of your plugin directory, you should use PHP's dirname() function:
<?php
echo '<img src="' . plugins_url( 'images/wordpress.png', dirname(__FILE__) ) . '" > ';
?>
You would then need to remove your file name to get the path.
Or use ``
ANSWER:
These solutions solutions are independant of where the file of your calling function is located. If your file is located in the plugins folder, or a subdirectory of it, then the above options would work. Otherwise, you'll need to resort to something along the lines of:
WP_PLUGIN_DIR
WordPress does have a constant defined, for the Plugins' folder:
Codex: https://codex.wordpress.org/Determining_Plugin_and_Content_Directories
Constants
WordPress makes use of the following constants when determining the path to the content and plugin directories. These should not be used directly by plugins or themes, but are listed here for completeness.
WP_CONTENT_DIR // no trailing slash, full paths only
WP_CONTENT_URL // full url
WP_PLUGIN_DIR // full path, no trailing slash
WP_PLUGIN_URL // full url, no trailing slash
// Available per default in MS, not set in single site install
// Can be used in single site installs (as usual: at your own risk)
UPLOADS // (If set, uploads folder, relative to ABSPATH) (for e.g.: /wp-content/uploads)
Or, If you can guarantee that the plugins folder is located in the normal place for a WordPress install, i_a's answer above answer above will work, no matter what directory your file (that you want to call this function from) is in.
Please see his more complete post in this thread, but so as to not have a "link only answer", I'll include here that it Essentially, it boils down to using the following (and turning it into a function):
$plugins_root = WP_CONTENT_DIR . '/plugins';
Or M07's post, also in this thread, here: https://stackoverflow.com/a/28525164/5411817
Kinda late to this party, but just in case some else stumbles upon this.
plugin_dir_path(__FILE__) will always return the current path (where the file calling it is located).
If you want the root, use the code below:
plugin_dir_path( dirname( __FILE__ ) )
You can then define a constant:
define( 'YOUR_PLUGIN_DIR', plugin_dir_path( dirname( __FILE__ ) ) );
require_once YOUR_PLUGIN_DIR . 'includes/admin-page.php'
require_once YOUR_PLUGIN_DIR . 'admin/classes.php'
You can define a constant into your main PHP file. It should be at the root of your plugin folder.
The file should be here : .../wp-content/plugins/plugin-folder/my-plugin.php
You can add into the file this line.
define( 'MYPLUGIN__PLUGIN_DIR_PATH', plugins_url( '', __FILE__ ) );
After you can use your new constant anywhere in your plugin.
public function Test()
{
$folder2 = MYPLUGIN__PLUGIN_DIR_PATH . '/folder1/folder2/';
// $folder2 = .../wp-content/plugins/plugin-folder/folder1/folder2/
}
I hope it will help someone.
As noted on the section Common Usage of Plugins Url function reference page, that's what worked for me:
If you are using the plugins_url() function in a file that is nested inside a subdirectory of your plugin directory, you should use PHP's dirname() function:
echo plugins_url('', dirname(__FILE__) );
The output for this was:
http://domain/app/wp-content/plugins/my-plugin
The file that called the function was my functions.php inside includes, so the complete path to my file was:
http://domain/app/wp-content/plugins/my-plugin/includes/functions.php
I will suggest following code. if you are accessing this function from any subfolder.
plugins_url( 'images/logo.png' , dirname(__FILE__ ));
Unfortunately, most of the answers here seem to forget about one important thing.
In addition to the plugins dir, plugins might be also in the Must-use plugins (mu-plugins) directory
Because of that, we need to check multiple directories.
An example function to do this:
function get_plugin_dir_path($pluginFolderName){
if ( defined( 'WPMU_PLUGIN_DIR' ) && file_exists( trailingslashit( WPMU_PLUGIN_DIR ) . $pluginFolderName ) ) {
return trailingslashit( WPMU_PLUGIN_DIR ) . $pluginFolderName;
} elseif ( defined( 'WP_PLUGIN_DIR' ) && file_exists( trailingslashit( WP_PLUGIN_DIR ) . $pluginFolderName ) ) {
return trailingslashit( WP_PLUGIN_DIR ) . $pluginFolderName;
}
return false;
}
plugin_dir_path( __FILE__ ) will give you plugin path of current file.
this is mean if you call this function like that inside "your_plugin_dir/sub_dir/file.php"
will return "your_plugin_dir/sub_dir/"
if you want to get the ROOT of your plugin directory, just change __FILE__ to __DIR__
plugin_dir_path( __DIR__ )
Here is a solution, when you are not inside the plugin root:
As of now with 4.7.5, WordPress does not have a get_plugins_root() function like there is a get_theme_root() function. This is probably because you really shouldn't ever need to modify plugins from your theme, and the plugins root directory never changes.
However, it can be useful if you need to programmatically affect plug-ins while developing themes.
Simply, as WP does for the theme root:
$plugin_root = WP_CONTENT_DIR . '/plugins';
Or, if you need a function, why not just do it the same way WordPress does it for the theme root?
Just make a copy of the function get_theme_root() from wp-includes/theme.php and paste it into your theme's functions.php file, rename the function to get_plugins_root(), simplify it, and change 'theme' to 'plugins' in the function...
get_plugins_root() {
$plugins_root = WP_CONTENT_DIR . '/plugins';
/**
* Filters the absolute path to the plugins directory.
*
* #since now
*
* #param string $plugins_root Absolute path to plugins directory.
*/
return apply_filters( 'plugins_root', $plugins_root );
}
With the path, you can now add the plug-ins folder name that you wish to affect.
$the_plugin_root = get_plugins_root()."/the-plugin-name/";
My solution has been to use inside plugin_dir_path DIR
plugin_dir_path( __DIR__ ) . $path_inside_plugin_folder;
The above should give you the absolute path to your plugin folder on the server, then you can load your variable with any file within your plugin folder
As mentioned by #tsl143 the function plugins_url() is what you want, along with the __FILE__ magic constant. If you call it from a file inside your plugin folder it will refer to that folder.
Example:
For the directory:
echo plugins_url( '' , __FILE__ );
//outputs: http://www.example.com/wp-content/plugins/my-plugin
For a file or subdirectory in your plugin directory:
echo plugins_url( 'images/logo.png' , __FILE__ );
//outputs: http://www.example.com/wp-content/plugins/my-plugin/images/logo.png
You can gain it by using this method
plugin_dir_url( __DIR__ )
The other solutions either won't work if called from a sub-directory of your plugin or they require that you to hard code your plugin's directory name or you need to define a global variable.
My solution uses a function that can be placed in any directory of your plugin without requiring that you to hard code something.
function get_my_plugin_root_dir()
{
// WP_PLUGIN_DIR will have something like "/home/michael/public_html/wp-content/plugins"
// __DIR__ will have something like "/home/michael/public_html/wp-content/plugins/my-plugin-folder/the-dir-being-called-from
// First, we remove WP's root plugin path from our __DIR__ path.
$path_to_this_files_dir_without_wp_plugin_dir = str_replace(WP_PLUGIN_DIR, '', __DIR__);
// Now, we're left with only our plugin's path, which looks like
// this: "/my-plugin-folder/the-dir-being-called-from"
// Next, we discard any sub-directories that are included with our
// plugin's path and keep the first directory in the path, our
// plugin's directory name.
$plugin_directory_name_only = explode(DIRECTORY_SEPARATOR, $path_to_this_files_dir_without_wp_plugin_dir)[1];
// Now $plugin_directory_name_only has "my-plugin-folder"
// Lastly, we build the plugin's complete root path using
// WP's root plugin directory and our plugin's root dir name.
return WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . $plugin_directory_name_only;
}
As of now, there isn't any function that will return only the full path of your plugin's base directory.
However, the constant WP_CONTENT_DIR is used by WordPress for just about that. But, even though, WordPress uses this constant, they warn us not to use it directly in our plugins or themes. That's because it can cause issues like when users change or rename their plugin's directory from the default one.
Using the plugin_dir_path() function will return the path of the file's directory from where it is called. So, if you call this function from a PHP file that is inside a subfolder of your plugin, it will return the path of that subfolder's directory and not your plugin's base directory.
Answer
Now, as a workaround, we can define a constant in a PHP file that is directly inside the plugin's base directory and then set its value to the result of calling plugin_dir_path( __FILE__ ). This way, we will be able to use that constant anywhere in the plugin to get the full path of the plugin's base directory.
So, open a PHP file located directly in your plugin's base directory. For instance:
../wp-content/plugins/myplugin/myplugin.php
Then, define a constant by setting its value to the result of calling plugin_dir_path() function. For instance:
define( 'MYPLUGIN_PLUGIN_DIR_PATH', plugin_dir_path( __FILE__ ) );
This constant now holds the path of your plugin's root directory. So, now, if you echo that constant from any file located in any directory of your plugin like this:
echo MYPLUGIN_PLUGIN_DIR_PATH;
It will print something like this:
/home/example.com/public_html/wp-content/plugins/myplugin/
This solution wasn't available when the original answer was accepted.
If the current file is two folders down into the plugin path, use this:
$plugin_path = plugin_dir_path(dirname(__FILE__, 2));
$plugin_url = plugin_dir_url(dirname(__FILE__, 2));
Note the number as the second parameter on dirname(), available since PHP v7.0.0.
The technique to use a constant works with this too, this time outside of the root-level plugin.php :
// from pluginname/src/API/Common/Constants.php
define( 'MYPLUGIN_PLUGIN_DIR_PATH', plugin_dir_path(dirname(__FILE__, 3)) );
Note this comment on the PHP Manual site:
Dirname likes to mess with the slashes.
So I normalize the path to avoid double slashes, and slashes that are wrong for the current OS:
$normalized = wp_normalize_path( $plugin_path . '/' . $required_file);
if (file_exists($normalized))
require_once $normalized;
else
die(__('Required file does not exist') . ": $normalized");
As others have stated, using plugin_dir_path(__FILE__) works to get the directory of your plugin if used within the main plugin file (e.g. plugins/myplugin/myplugin.php.
But what if you want to know the plugin directory from another file in your plugin? Well what I like to do is define a constant in my main plugin file like this;
// plugins/myplugin/myplugin.php
define('MYPLUGIN_PATH', plugin_dir_path(__FILE__));
Then in other php files within your plugin, you can use MYPLUGIN_PATH (a constant) anywhere you like, without knowing the directory structure!
rather than take the advice of someone who's not using your server (and continue guessing at it...)
why not just load a so-called "Classic" theme, and see what you get?
You're either going to get a relative, or an absolute path. It's not random. figure it out. if you don't like the output, change the function/ args. If you don't know the function names, Install Visual Studio Code, and one of the several WordPress autocomplete / intellisense plugins. It basically writes the code for you.
e.g. ./wp-content/themes/classic/footer.php
wp_footer();
echo '<br><strong>plugin_dir_url(dirname(__FILE__))</strong><br> '. plugin_dir_url(dirname(__FILE__));
echo '<br><strong>plugins_url()</strong><br> '. plugins_url();
echo '<br><strong>__FILE__</strong><br> ' .__FILE__ .'<br>';
?>
go from there.
Background Information:
I'm using Symfony Console Component to write a console application that is wrapped into a Shell object. I wrote a command named console:reload that empties the array of commands from the Application object, and re-adds commands classes listed under certain directory.
This command is run when the shell starts, so, the Application is loaded with the available commands. The classes being loaded are located in a special directory and should follow a simple name rule: <CommandName>Command.php:
// Inside ReloadCommand->execute() method...
$pamperoApp = $this->getApplication();
$pamperoApp->clearCommands();
$namespace = "pampero\\cli\\modules";
foreach(glob(MODULES_DIR . "/*/*Command.php") as $command) {
$class = str_replace(".php", "", $namespace . "\\" . basename(dirname($command)) . "\\" . basename($command));
$this->getApplication()->add(new $class);
}
The autoload provided by Symfony (Composer?) ClassLoader is used:
// Main entry point...
loader = require_once __DIR__ . '/../vendor/autoload.php';
$loader->set('pampero', __DIR__ . '/../..');
I read the code from ClassLoader class and what it does is to store file name path, so no object caching there.
Here's the problem:
I launch the app: php packages.php. The shell appears after ReloadCommand command being executed. A list of available and loaded commands are ready to be used.
If I create a new file, let's say: ExampleCommand.php, and then I type: console:reload, the new command will indeed be added. Now, If I modify the code inside ExampleCommand.php and run console:reload again, the changes made to the class won't take effect.
But that's not all. If I remove the example file, call console:reload, create the file again and run: console:reload the command will be added.
Reading:
I have read APC related things, and before creating new classes I have done things like:
// Prior adding commands in ReloadCommand
apc_clear_cache();
apc_clear_cache('user');
apc_clear_cache('opcode');
Without luck. I've also run apc.php and enabled/disabled apc.enable_cli option. None of those things creates the object represented by the modified file.
So my hints and clues about the problems turns to be classes caching when a file/class is found. But how to avoid that for this special case? I don't want to restart the shell if some extra funcionality is added through classes.
Any ideas?
I will answer my own question as I found a solution.
Ok, clues were fine. The problem was that PHP including a file binds the symbols for later use while parsing the file.
So, I needed some kind of instrospection. After reading/googling/searching for all night, finally I've ended up finding Runkit.
Runkit documentation can be found here. I know that is not the best thing you can do with your code design. But for my project needs, the truth is that Reflection was needed.
Here is the modified code using Runkit:
protected function execute(InputInterface $input, OutputInterface $output)
{
// Gets a reference to the console application and removes all commands
$pamperoApp = $this->getApplication();
$pamperoApp->clearCommands();
// Adds default commands and add this command
$pamperoApp->addCommands($pamperoApp->getDefaultCommands());
$pamperoApp->add($this);
$namespace = "pampero\\cli\\modules";
foreach(glob(MODULES_DIR . "/*/*Command.php") as $filename) {
$className = str_replace(".php", "", $namespace . "\\" . basename(dirname($filename)) . "\\" . basename($filename));
// Do not add this command again. This command shouldn't be modified on-the-fly
if (get_class($this) !== $className) {
$class = new $className();
// Redefines the class definition
runkit_import($filename, RUNKIT_IMPORT_CLASSES | RUNKIT_OVERRIDE_OBJECTS | RUNKIT_IMPORT_OVERRIDE);
$pamperoApp->add($class);
}
}
}
I'm drawing a blank. I have code working locally (which is MAMP). When moving to a nginx ubuntu box (running php-fpm), for some reason, phpactiverecord is acting up.
I finally traced it down to this - All of my model classes, I have to load manually. If I add a require_once() underneath my code, then it works fine. If I don't, then I get errors like:
PHP Fatal Error: Class not found ... on the models I've created..
Does anyone have ANY idea what direction I could troubleshoot this in? I checked permissions to the models folder (which is not in the public root), echo'd out the path that is sent over to cfg->set_model_directory is correct, etc..
This sound like a nginx or php thing? I'm guessing nginx since this works on my MAMP?
Doesn't work:
ActiveRecord\Config::initialize(
function ($cfg) {
$cfg->set_model_directory(BASE_PATH . '/models');
$cfg->set_connections(
array(
'development' => 'mysql://blah:removed#localhost/com_dbname'
)
);
}
);
Works:
ActiveRecord\Config::initialize(
function ($cfg) {
$cfg->set_model_directory(BASE_PATH . '/models');
$cfg->set_connections(
array(
'development' => 'mysql://blah:removed#localhost/com_dbname'
)
);
}
);
require_once(BASE_PATH . '/models/model1.php');
require_once(BASE_PATH . '/models/model2.php');
Update
Adding in actual code to help identify issue:
require_once ('../lib/php-activerecord/ActiveRecord.php');
ActiveRecord\Config::initialize(
function ($cfg) {
$cfg->set_model_directory('/var/www/uc1/models');
$cfg->set_connections(
array(
'development' => 'mysql://test_usr:test_pwd#localhost/test_db'
)
);
}
);
require_once ('/var/www/uc1/models/ucurls.php'); //Name of model file. Must manually include to get this to work on my nginx server.
$_record = UCUrls::find_by_urlkey('example.com/123');
echo "urlkey=" . $_record->urlkey;
I solved this issue in windows adding a line in the file ActiveRecord.php,
in the function activerecord_autoload($class_name)
at the line 39 or 40
$file = "$root/$class_name.php";
//add this line
$file = strtolower($file);
Set trace in ActiveRecord.php too look where are ActiveRecord is searching for models.
But I think your issue is in filesystem - Mac OS X by default uses Case Insensitive filesystem, while Ubuntu's Case Sensitive filesystem.
So your model UCUrls should be in file /var/www/uc1/models/UCUrls.php, not in /var/www/uc1/models/ucurls.php