Enqueueing scripts if a file exists - php

I work with wordpress on my child theme.
My site is installed into mydomain.xx/install, but runs from mydomain.xx.
My functions.php works and looks like this:
<?php
/* Script in head */
function carica_scripts() {
/* Common scripts */
// insert scripts here, if some
/* Page-based script */
$pageId = get_the_ID();
$pageType = get_post_type();
$myBaseURL = get_stylesheet_directory_uri() . '/js/';
/* Page-type scripts */
if($pageType == "product") {
wp_enqueue_script('CondAll', $myBaseURL . 'CondAll.js', array('jquery'));
wp_enqueue_script('CondShipping', $myBaseURL . 'CondShipping.js', array('jquery'));
}
/* Page-id scripts */
if($pageId == "1") {
wp_enqueue_script('Cond1', $myBaseURL . 'Cond1.js', array('jquery'));
}
if($pageId == "294") {
wp_enqueue_script('Cond294', $myBaseURL . 'Cond294.js', array('jquery'));
}
if($pageId == "318") {
wp_enqueue_script('Cond318', $myBaseURL . 'Cond318.js', array('jquery'));
}
if($pageId == "232") {
wp_enqueue_script('Cond232', $myBaseURL . 'Cond232.js', array('jquery'));
}
/* END of page-based script */
}
add_action( 'wp_enqueue_scripts', 'carica_scripts' );
?>
What I want to achieve is avoiding all the ifs on $pageId, and to auto-enqueue jQuery script CodXXX.js on page id XXX if the relative file exists in the subdirectory /js/ of my child theme.

file_exists() expects an absolute path to a file rather than a URL.
Use get_stylesheet_directory() to get the path you need. Also get_the_ID() shouldn't be used outside of the loop.
Example:
/*
* Enqueue CondXXX.js on page XXX if file CondXXX.js exists
*/
function carica_scripts() {
global $post;
// Check we're on a page.
if ( ! is_page() ) {
return false;
}
// Build the filename to check.
$handle = 'Cond' . $post->ID;
$relpath = '/js/' . $handle . '.js';
// Get path + url to file.
$file_path = get_stylesheet_directory() . $relpath;
$file_url = get_stylesheet_directory_uri() . $relpath;
if ( file_exists( $file_path ) ) {
wp_enqueue_script( $handle, $file_url, array( 'jquery' ) );
}
}
add_action( 'wp_enqueue_scripts', 'carica_scripts' );

The answer given by Nathan Dawson does not work in my case, I had to do some workarounds. I ended up with the following code:
/* Load scripts in head */
function carica_scripts() {
/* Common scripts */
/* END of common scripts */
/* Page-based script */
$pageId = get_the_ID();
$pageType = get_post_type();
$handle = 'Cond' . $pageId;
$file = $handle .'.js';
$relPath = '/js/';
$styleSheet_path = get_stylesheet_directory();
$domain_base = 'mydomain.it/public_html/';
$start_pos = strpos ( $styleSheet_path, $domain_base) + strlen ($domain_base);
$basePath = substr ( $styleSheet_path, $start_pos); // I need everything after 'mydomain.it/public_html/'
$file_path = $basePath. $relPath . $file;
$enqueue_path = get_stylesheet_directory_uri() . $relPath;
$enqueue_file = $enqueue_path . $file;
/* if page-type is ... (product, in this case) */
if($pageType == "product") {
wp_enqueue_script('CondAll', $enqueue_path . 'CondAll.js', array('jquery'));
wp_enqueue_script('CondShipping', $enqueue_path . 'CondShipping.js', array('jquery'));
}
/* If page id is... (1, in this case - because page 1 is not product but I want CondAll here too) */
if($pageId == "1") {
wp_enqueue_script('CondAll', $enqueue_path . 'CondAll.js', array('jquery'));
}
/* auto load script CondXXX.js from subdir js/ if file exists */
if ( file_exists( $file_path ) ) {
wp_enqueue_script( $handle, $enqueue_file, array( 'jquery' ) );
}
/* END of page-based script */
}
add_action( 'wp_enqueue_scripts', 'carica_scripts' );
Now the the scripts load.

Related

Including libraries from node_modules in Wordpress Plugin

I am creating a ReactJs and wordpress plugin. I have created the standalone Reactjs control and I now want to include my reactJS libraries in the node_modules folder in my wordpress php file like so. Is this the right way to do it? Wordpress is able to find the node_modules folder and the libraries that I have enqueued but not the libraries that the enqueued files depend on(which are present in the node_modules folder).
add_action( 'wp_enqueue_scripts', 'FacebookAlbums_enqueue_scripts' );
function FacebookAlbums_enqueue_scripts() {
wp_enqueue_script( 'react', plugin_dir_url( __FILE__ ) . 'node_modules/react/umd/react.production.min.js' );
wp_enqueue_script( 'react-dom', plugin_dir_url( __FILE__ ) . 'node_modules/react-dom/umd/react-dom.production.min.js' );
wp_enqueue_script( 'react-slick', plugin_dir_url( __FILE__ ) . 'node_modules/react-slick/lib/slider.js' );
wp_enqueue_script( 'react-image-lightbox', plugin_dir_url( __FILE__ ) . 'node_modules/react-image-lightbox/dist/main.js' );
wp_enqueue_script( 'babel', 'https://npmcdn.com/babel-core#5.8.38/browser.min.js', '', null, false );
wp_enqueue_script( 'FacebookAlbums', plugin_dir_url( __FILE__ ) . 'FacebookAlbums.js' );
wp_enqueue_style( 'FacebookAlbums', plugin_dir_url( __FILE__ ) . 'FacebookAlbums.css' );
}
Place this file in the same folder as your package.json that contains your dependencies:
<?php
// the generic wp node_modules loader
$package = file_get_contents(__DIR__ . '/package.json');
$package = json_decode($package, true);
foreach ($package['dependencies'] as $dep => $version) {
$subpackage = file_get_contents(__DIR__ . "/node_modules/$dep/package.json");
$subpackage = json_decode($subpackage, true);
$use = 'main';
if (isset($subpackage['browser'])) {
$use = 'browser';
}
if (isset($subpackage[$use])) {
$deps = array();
if (strpos($dep, 'jquery') !== false) {
$deps[] = 'jquery';
}
wp_enqueue_script("node_module-$dep", plugin_dir_url(__FILE__) . "node_modules/$dep/" . $subpackage[$use], $deps, $subpackage['version']);
}
if (isset($subpackage['style'])) {
wp_enqueue_style("node_module-$dep", plugin_dir_url(__FILE__) . "node_modules/$dep/" . $subpackage['style']);
}
}
You'll need to require this file somewhere in your plugin. (This will not work with 100% of packages, modify it according to your project - this is a work in progress).

wordpress get url of registered script

If I register a script or style (using wp_register_script() or wp_register_style()), is there a way I can get the URL of that script/style?
(If you must know why, I'm trying to put those URL's into another function that generates prefetch link tags so I can prefetch certain scripts/styles for a performance boost in my site.)
Just in case someone is still looking for this:
<?php
function invdr_get_script_uri_by_handler( $handler ){
//Get an instance of WP_Scripts or create new;
$wp_scripts = wp_scripts();
//Get the script by registered handler name
$script = $wp_scripts->registered[ $handler ];
if ( file_exists( ABSPATH . $script->src ) ){
return ABSPATH . $script->src;
}
return false;
}
add_action( 'wp_enqueue_scripts', 'invdr_get_script_uri_by_handler', PHP_INT_MAX );
Tested in wordpress 5.0
You can use wp_scripts() to get the instance of the WP_Scripts class which contains the registered scripts (this class extends WP_Dependencies).
Basically, try looking in:
$wp_scripts = wp_scripts();
var_dump( $wp_scripts->registered );
var_dump( $wp_scripts );
Here's how I've accomplished this in a self-authored plugin to help me enhance dependencies within WordPress:
// Convert relative URL to absolute?
$absolute = true;
$handle = 'your_stylesheet_handle';
$helper = wp_styles();
$object = $helper->registered[ $handle ];
$src = $object->src;
if (
$absolute
&& $helper->in_default_dir( $src )
) {
$src = $helper->base_url . $src;
}
$ver = $object->ver;
if ( ! is_null( $ver ) && empty( $ver ) ) {
$ver = $helper->default_version;
}
if ( isset( $helper->args[ $handle ] ) ) {
$ver = $ver ? $ver . '&' : '';
$ver .= $helper->args[ $handle ];
}
$src = add_query_arg( 'ver', $ver, $src );
$stylesheet_url = urldecode_deep( $src );
Note that the absolute URL conversion is directed towards handling assets registered by WordPress core, as they're typically relative URLs.

PHP define multiple constants in an array

Hi I am really bad and a total newbie to PHP. Need some help.
I am trying to define a few constants in my site:
Code 1
define('SITE_ROOT',$_SERVER['DOCUMENT_ROOT'] . '/');
// Check if CORE_PATH is already defined else define here
defined('CORE_PATH') or define('CORE_ROOT', SITE_ROOT . '/CORE');
define('INC_PATH', IAO_ROOT . '/inc/');
define('LAYOUTS_PATH', IAO_ROOT . 'layouts/');
define('BLOCKS_PATH', SECTIONS_PATH . 'blocks/');
define('STATIC_PATH', BLOCKS_PATH . 'static/');
Apart from the above example I have another 10-15 more constants to define. I want to know is it correct to define each constant in one line each or can I do something like below:
Code 2
define (
$constant = array (
'SITE_ROOT',
'CORE_PATH',
'INC_PATH' ,
'LAYOUTS_PATH',
'BLOCKS_PATH',
'STATIC_PATH'
),
$path = array(
$_SERVER['DOCUMENT_ROOT'] . '/',
SITE_ROOT . '/CORE',
CORE_PATH . '/inc',
CORE_PATH . '/layout',
CORE_PATH . '/blocks',
CORE_PATH . '/static'
)
);
define ( $constant, $path);
While Code 1 is working fine on my site, Code 2 is not working for me.
Kindly advise me what is the correct way.
UPDATE:
Updated this question as per #LasVegasCoder. does not work.
<?php
//Create array of paths --example from your path ***use right paths***;
$path = array(
'SITE_ROOT . ' => $_SERVER['DOCUMENT_ROOT'],
'CORE_PATH' => SITE_ROOT . '/core',
'INCLUDE_PATH' => SITE_ROOT . '/inc',
'LAYOUT_PATH' => SITE_ROOT . '/layout',
'BLOCK_PATH' => SITE_ROOT . '/blocks',
'STATIC_PATH' => SITE_ROOT . '/static'
);
//usage:
createPath( $path );
//Testiing
echo SITE_ROOT; ?></br>
<?php echo CORE_PATH; ?></br>
<?php echo INCLUDE_PATH; ?></br>
<?php echo LAYOUT_PATH; ?></br>
<?php echo BLOCK_PATH; ?></br>
<?php echo STATIC_PATH; ?></br>
<?php
function createPath( $path )
{
if( empty( $path ) )
{
die("Array of path required!");
}
foreach( $path as $constant => $path )
{
if(!defined( strtoupper($constant) ) )
{
define( strtoupper($constant), $path . '/');
}
}
}
Well still it does not work. Any idea and solutions?
Create Paths Dynamically
With this tiny function, you can create your paths as array of key => value, pass it to the function to create the paths for your application.
Create array of paths
using example in this question -- use right paths
$path = array(
'SITE_ROOT' => $_SERVER['DOCUMENT_ROOT'],
'CORE_PATH' => '/core',
'INCLUDE_PATH' => '/inc',
'LAYOUT_PATH' => '/layout',
'BLOCK_PATH' => '/blocks',
'STATIC_PATH' => '/static'
);
usage create paths using the function:
createPath( $path );
Testing path
echo CORE_PATH;
OUTPUT
/core/
Create a function to handle paths.
function createPath( $path )
{
if( empty( $path ) )
{
die("Array of path required!");
}
foreach( $path as $constant => $path )
{
if(!defined( strtoupper($constant) ) )
{
// define( strtoupper($constant), $path . '/');
define( strtoupper($constant), realpath( dirname( __FILE__) ) . $path . '/');
}
}
}
youpage.php
<?php
/**Create array of paths array of $constant to $path;
* i.e $path = array( 'THIS_CONSTANT' => '/this/path', 'WEB_ROOT' => '/path/to/webroot' );
* usage:
* `createPath( $path );`
* Test: `echo WEB_ROOT;` OUTPUT: '/path/to/webroot/'
*
* - How to Include another scripts:
* require_once CORE_PATH . 'Config.php';
* require_once INCLUDE_PATH . 'Database.php';
* require_once LAYOUT_PATH 'Header.php';
* require_once LAYOUT_PATH 'Body.php';
* require_once LAYOUT_PATH 'Footer.php';
*/
$path = array(
'SITE_ROOT' => $_SERVER['DOCUMENT_ROOT'],
'CORE_PATH' => '/core',
'INCLUDE_PATH' => '/inc',
'LAYOUT_PATH' => '/layout',
'BLOCK_PATH' => '/blocks',
'STATIC_PATH' => '/static'
);
//usage:
createPath( $path );
// Test. You can echo path, include | require e.g:
echo STATIC_PATH;
function createPath( $path )
{
if( empty( $path ) )
{
die("Array of path required!");
}
foreach( $path as $constant => $path )
{
if(!defined( strtoupper($constant) ) )
{
// define( strtoupper($constant), $path . '/');
define( strtoupper($constant), realpath( dirname( __FILE__) ) . $path . '/');
}
}
}
Test a DEMO Version online
Hope this helps!

How to Move file in wordpress on plugin activation

I want to move file in wordpress on plugin activation . i have written a code for this but it is not working .
function onactivation_install(){
$src = ABSPATH . 'wp-content/plugins/sinetiks-schools/plugin_list.php';
$dest = get_template_directory();
$full_path = $dest.'/';
$flag = wp_handle_upload($src,$full_path);
var_dump($flag); }
register_activation_hook( __FILE__,'onactivation_install' );
pass this parameter
$flag = wp_handle_upload($src,array( 'test_form' => false ));

Woocommerce - overriding the template through a plugin

I have a question: is there a way to override WooCommerce's default template through a plugin the same way you'd do it with a theme?
I have this code:
Class WoocommerceOverride {
public function woocommerce_locate_template( $template, $template_name, $template_path ) {
$plugin_path = SPSL_PLUGIN_PATH;
global $woocommerce;
$_template = $template;
if ( ! $template_path ) $template_path = $woocommerce->template_url;
$plugin_path .= '/woocommerce/';
// Look within passed path within the theme - this is priority
$template = locate_template(
array(
$template_path . $template_name,
$template_name
)
);
// Modification: Get the template from this plugin, if it exists
if ( ! $template && file_exists( $plugin_path . $template_name ) )
$template = $plugin_path . $template_name;
// Use default template
if ( ! $template )
$template = $_template;
//echo $template."<br>";
// Return what we found
return $template;
}
}
add_filter( 'woocommerce_locate_template', array('WoocommerceOverride', 'woocommerce_locate_template'), 10, 3 );
The problem with this code is that it works only partially. On some parts it works, on other parts it does not. For example, I can't customize archive-product.php at all. Whatever I write in there, whether code or plain text, I just don't get any results.
I copied the exact same template files from my plugin folder into my theme folder and it works. However, as I need this as a plugin, I can't go the theme route.
Many thanks.
Using filters wc_get_template_part we can override default WooCommerce template part's.
Using filters woocommerce_locate_template we can override default WooCommerce template's.
Try below example code snippet.
<?php
/**
* Override default WooCommerce templates and template parts from plugin.
*
* E.g.
* Override template 'woocommerce/loop/result-count.php' with 'my-plugin/woocommerce/loop/result-count.php'.
* Override template part 'woocommerce/content-product.php' with 'my-plugin/woocommerce/content-product.php'.
*
* Note: We used folder name 'woocommerce' in plugin to override all woocommerce templates and template parts.
* You can change it as per your requirement.
*/
// Override Template Part's.
add_filter( 'wc_get_template_part', 'override_woocommerce_template_part', 10, 3 );
// Override Template's.
add_filter( 'woocommerce_locate_template', 'override_woocommerce_template', 10, 3 );
/**
* Template Part's
*
* #param string $template Default template file path.
* #param string $slug Template file slug.
* #param string $name Template file name.
* #return string Return the template part from plugin.
*/
function override_woocommerce_template_part( $template, $slug, $name ) {
// UNCOMMENT FOR #DEBUGGING
// echo '<pre>';
// echo 'template: ' . $template . '<br/>';
// echo 'slug: ' . $slug . '<br/>';
// echo 'name: ' . $name . '<br/>';
// echo '</pre>';
// Template directory.
// E.g. /wp-content/plugins/my-plugin/woocommerce/
$template_directory = untrailingslashit( plugin_dir_path( __FILE__ ) ) . 'woocommerce/';
if ( $name ) {
$path = $template_directory . "{$slug}-{$name}.php";
} else {
$path = $template_directory . "{$slug}.php";
}
return file_exists( $path ) ? $path : $template;
}
/**
* Template File
*
* #param string $template Default template file path.
* #param string $template_name Template file name.
* #param string $template_path Template file directory file path.
* #return string Return the template file from plugin.
*/
function override_woocommerce_template( $template, $template_name, $template_path ) {
// UNCOMMENT FOR #DEBUGGING
// echo '<pre>';
// echo 'template: ' . $template . '<br/>';
// echo 'template_name: ' . $template_name . '<br/>';
// echo 'template_path: ' . $template_path . '<br/>';
// echo '</pre>';
// Template directory.
// E.g. /wp-content/plugins/my-plugin/woocommerce/
$template_directory = untrailingslashit( plugin_dir_path( __FILE__ ) ) . 'woocommerce/';
$path = $template_directory . $template_name;
return file_exists( $path ) ? $path : $template;
}
Few months ago the i had the same requirements. So searched a bit more on the net and found useful code which helped me(with a little more customization as per my requirements).
For a detailed code with explanation check this and this link. The approach might be different than what you currently using but it results in overriding woocommerce templates in plugin
You should try adding this code before your // Use default template code:
if( $template_name == '{template part name}') {
$template = $plugin_path . $template_name;
}
In my case {template part name} was global/quantity-input.php
You can find out your exact template part names by temporary adding this line to your code:
print_r($template_name);
I know it's a bit late for answer here but maybe it will be useful for someone else. And keep in mind woocommerce_locate_template is depricated. So there is probably more 'up to date' solution somewhere out there.

Categories