Why does home_url() not work with filemtime() in WordPress? - php

I wanted to start automatically changing my enqueue version so I don't have to manually change it after a file edit so I thought about using filemtime() to pull the time but for some reason when I use it with site_url() or home_url it doesn't work:
function bootstrap_enqueue() {
$bootstrap_file = home_url() . '/css/bootstrap.css';
if (file_exists($bootstrap_file)) :
$bootstrap_ver = date("y.m.d", filemtime($bootstrap_file));
else :
$bootstrap_ver = '1.0.0';
endif;
wp_enqueue_style('bootstrap-style', $bootstrap_file, $bootstrap_ver);
}
add_action('wp_enqueue_scripts', 'bootstrap_enqueue');
but when I pass:
wp_enqueue_style('bootstrap-style', home_url() . '/css/bootstrap.css', '1.0' );
it works. I've researched and read:
Alternative to WordPress's get_site_url()
Get the last modified date of a remote file
Get last modified file in a directory
filemtime
but I haven't found an answer to why filemtime() it's work in WordPress with home_url?
EDIT:
Further testing I've tried:
wp_enqueue_style('bootstrap-style', $bootstrap_file, array(), $bootstrap_ver);
thinking it might be a sequencing issue but still doesn't work. I've moved the CSS file into the theme's directory and tried:
$bootstrap_file = get_template_directory_uri() . '/css/bootstrap.css';
if (file_exists($bootstrap_file)) :
$bootstrap_ver = date("y.m.d", filemtime($bootstrap_file));
else :
$bootstrap_ver = '1.0.0';
endif;
wp_enqueue_style('bootstrap-style', $bootstrap_file, array(), $bootstrap_ver);
all of them are still producing the same result and the version is being pushed to 1.0.0 so I think it has something to do with $bootstrap_file = home_url() . '/css/boostrap.css'; just not sure what.
In the head I'm returned what appears to be correct:
<link rel='stylesheet' id='bootstrap-style-css' href='http://path/to/server/css/bootstrap.css?ver=1.0.0' type='text/css' media='all' />
but the Bootstrap file isn't rendering.

I think the reason is that PHP filesystem functions don't go off of URLs but absolute paths to files. So we need both the URL and the Absolute Path to the file so we can ensure it exists and get the file timestamp:
function bootstrap_enqueue() {
// Roots
// $bootstrap_abs = ASBSPATH . '/css/bootstrap.css';
// $bootstrap_url = home_url() . '/css/bootstrap.css';
$bootstrap_abs = get_stylesheet_directory() . '/css/bootstrap.css';
$bootstrap_url = get_stylesheet_directory_uri() . '/css/bootstrap.css';
if( file_exists( $bootstrap_abs ) ) :
$bootstrap_ver = date( "y.m.d", filemtime( $bootstrap_abs ) );
else :
$bootstrap_ver = '1.0.0';
endif;
wp_enqueue_style('bootstrap-style', $bootstrap_url, array(), $bootstrap_ver);
}
add_action('wp_enqueue_scripts', 'bootstrap_enqueue');

Close -- I believe the issue is that filemtime needs a file path asset, whereas you're trying to feed it a web URL.
I'd try something like using getcwd() to point to the file instead.

The 'home_url' function echos out the home URL, which will break your code. Use get_home_url() instead, because that function returns the value, which means you can store it in a variable or echo it.
wp_enqueue_style('bootstrap-style', get_home_url() . '/css/bootstrap.css', '1.0' );
EDITED
The PHP filemtime() function needs to get the files URL from the server root, but the wordpress wp_enqueue_style() function needs the host root URL. The following changes to your code might work as long as if your CSS is still in your root directory. If it is is your theme directory just change get_home_url() to get_template_directory_uri(). If that doesn't work, then smoke me a kipper, I'll be back for breakfast.
function bootstrap_enqueue() {
$bootstrap_file = get_home_url() . '/css/bootstrap.css';
if (file_exists($bootstrap_file)) :
$bootstrap_ver = date("y.m.d", filemtime($_SERVER["DOCUMENT_ROOT"] . '/css/bootstrap.css'));
else :
$bootstrap_ver = '1.0.0';
endif;
wp_enqueue_style('bootstrap-style', $bootstrap_file, $bootstrap_ver);
}
add_action('wp_enqueue_scripts', 'bootstrap_enqueue');

Related

Custom Upload Directory does not change attachment meta

I'm trying to make a download script for a password protected wordpress site. To make use of PHPs readfile() function I need to retrieve the full attachment URL based on it's ID i am passing to the download script.
I made a Custom Post Type named Downloads and also changed it's upload directory to a folder inside wp-content also named downloads.
Here is the code for it:
add_filter( 'upload_dir', 'custom_upload_directory' );
function custom_upload_directory( $args ) {
$id = $_REQUEST['post_id'];
$parent = get_post( $id )->post_parent;
if( "downloads" == get_post_type( $id ) || "downloads" == get_post_type( $parent ) ) {
$args['path'] = WP_CONTENT_DIR . '/downloads';
$args['url'] = WP_CONTENT_URL . '/downloads';
}
return $args;
}
Upload works fine and when I click the link to the desired file, the ID is passed to a script via $_POST, which also works fine. But I just can't figure out a way to get the right file URL. Here's what I tried:
wp_get_attachment_url( $id ); // returns: example.com/wp-content/uploads/html/theme/wp-content/downloads/filename.ext
wp_get_attachment_link( $id ); // returns: slug
get_attachment_link( $id ); // returns: example.com/downloads/file (without .ext)
get_attached_file( $id, true ); // returns: html/theme/wp-content/downloads/filename.ext
get_post_meta( $id, '_wp_attached_file', false ); // returns: html/theme/wp-content/downloads/filename.ext
wp_get_attachment_metadata( $id ); // returns nothing
What I expected any of those functions to return was example.com/wp-content/downloads/filename.ext
But as you can see, some mix up the default upload directory and combine it with the new one while others just return half of the full URL (html/theme/... it's the directory the website sits on the server). So any ideas would be appreciated.
Hours, days and even weeks later I finally found an answer and modified it to fit my needs. I came as far as displaying the right URL (the modified one) inside the file upload lightbox of Wordpress. But after publishing/updating the post it went back to the same old .../wp-content/uploads/file.ext URL.
Someone else, somewhere else got exactly the same problem and fortunately it is said there, that you must not just alter $args['path'] and $args['url'] but you also have to alter basedir, baseurl and subdir.
So, the complete code to change a custom post types upload directory (in this case I chose the directory .../wp-content/downloads) is the following:
add_filter( 'upload_dir', 'change_upload_dir' );
function change_upload_dir( $args ) {
$id = $_REQUEST['post_id'];
if( get_post_type( $id ) == 'downloads' ) {
$args['basedir'] = wp_normalize_path( WP_CONTENT_DIR . 'downloads' );
$args['baseurl'] = content_url() . '/downloads';
$args['path'] = $args['basedir'];
$args['url'] = $args['baseurl'];
$args['subdir'] = '';
return $args;
}
}
So now, calling wp_get_attachment_url() finally results in something like example.com/wp-content/downloads/file.ext

Replace wp-content in image urls wordpress

I've changed my wp-content folder to a folder called stuff and am trying to change my image urls in existing posts with a function rather than a SQL query...
I've placed this in my function.php hoping it would work, but the images are still using the 'wp-content' folder?
define('WP_UPLOADSURL', 'http://' . $_SERVER['HTTP_HOST']);
add_filter( 'pre_option_upload_url_path', function( $upload_dir_uri ){
return str_replace( WP_UPLOADSURL . '/wp-content/', WP_UPLOADSURL . '/stuff/', $upload_dir_uri );
});
I just needed to add the filter to the_content not the pre_option_upload_url_path.
define('WP_UPLOADSURL', 'http://' . $_SERVER['HTTP_HOST'] . '/');
add_filter( 'the_content', function( $upload_dir_uri ){
return str_replace( WP_UPLOADSURL . '/wp-content/', WP_UPLOADSURL . '/stuff/', $upload_dir_uri ); /* Again Change stuff */
});

wordpress - if is_bbPress() register jquery

i use this code to deregister jquery from wp_head():
<?php if ( !is_admin() ) wp_deregister_script('jquery'); wp_head(); ?>
i want jquery just added when user on bbpress page, but it's not working:
<?php
if (is_bbPress()) (wp_register_script('jquery'); wp_head();}
else (!is_admin()) (wp_deregister_script('jquery'); wp_head();}
?>
can somebody help me fix this please
The proper way to enqueue scripts and styles is to use wp_enqueue_script:
http://codex.wordpress.org/Function_Reference/wp_enqueue_script
So, for example:
function my_enqueue_script() {
if ( is_bbPress() ) {
// The name used as a handle for the script
$handle = 'script-name';
// The url to the script
$src = get_template_directory_uri() . '/js/example.js';
// Array of the handles of all the registered scripts that must be loaded before this script
$deps = array();
// The version number of the script (if it has one)
$ver = '1.0.0';
// Should the script be placed in the document footer or the head?
$in_footer = true;
wp_enqueue_script( $handle, $src, $deps, $ver, $in_footer );
}
}
add_action( 'wp_enqueue_scripts', 'my_enqueue_script' );

How to add "latin-extended" into a php query for a WordPress theme?

my title doesnt really tell anything. So I'll try to be clear. I am using a wordpress theme and it has google fonts pre-installed. However the included php for the fonts doesnt contain latin-extended option. How should I add the "&subset=latin,latin-ext" ?
The code follows:
foreach($googlefonts as $googlefont) {
if(!in_array($googlefont, $default)) {
$themename_customfont = str_replace(' ', '+', $googlefont). ':300,300italic,400,400italic,700,700italic,900,900italic|' . $themename_customfont;
}
}
if ($themename_customfont != "") {
function google_fonts() {
global $themename_customfont;
$protocol = is_ssl() ? 'https' : 'http';
wp_enqueue_style( 'themename-googlefonts', "$protocol://fonts.googleapis.com/css?family=". substr_replace($theretailer_customfont ,"",-1) . "' rel='stylesheet' type='text/css" );
}
add_action( 'wp_enqueue_scripts', 'google_fonts' );

How to safely get full URL of parent directory of current PHP page

I'm using:
$domain = $_SERVER['HTTP_HOST'];
$path = $_SERVER['SCRIPT_NAME'];
$themeurl = $domain . $path;
But this of course gives the full URL.
Instead I need the full URL minus the current file and up one directory and minus the trailing slash.
so no matter what the browser URL domain is eg localhost, https://, http://, etc that the full real (bypassing any mod rewrites) URL path of the parent directory is given without a trailing slash.
How is this done?
Safely so no XSS as I guess (from reading) using anything but 'SCRIPT_NAME' has such risk.. not sure though ofc.. just been reading a ton trying to figure this out.
examples:
if given:
https://stackoverflow.com/questions/somequestions/index.php
need:
https://stackoverflow.com/questions
without the trailing slash.
and should also work for say:
http://localhost/GetSimple/admin/load.php
to get
http://localhost/GetSimple
which is what I'm trying to do.
Thank you.
Edit:
Here's the working solution I used:
$url = isset($_SERVER['HTTPS']) ? 'https://' : 'http://';
$url .= $_SERVER['SERVER_NAME'];
$url .= htmlspecialchars($_SERVER['REQUEST_URI']);
$themeurl = dirname(dirname($url)) . "/theme";
it works perfectly.
Thats easy - using the function dirname twice :)
echo dirname(dirname('https://stackoverflow.com/questions/somequestions/index.php'));
Also note #Sid's comment. When you you need the full uri to the current script, with protocol and server the use something like this:
$url = isset($_SERVER['HTTPS']) ? 'https://' : 'http://';
$url .= $_SERVER['SERVER_NAME'];
$url .= $_SERVER['REQUEST_URI'];
echo dirname(dirname($url));
I have more simple syntax to get parent addres with port and url
lets try my code
dirname($_SERVER['PHP_SELF'])
with this code you can got a direct parent of adres
if you want to 2x roll back directory you can looping
dirname(dirname($_SERVER['PHP_SELF']))
dirname is fungtion to get parent addrest web and $_SERVER['PHP_SELF'] can showing current addres web.
thakyou Sir https://stackoverflow.com/users/171318/hek2mgl
I do not suggest using dirname()as it is for directories and not for URIs. Examples:
dirname("http://example.com/foo/index.php") returns http://example.com/foo
dirname("http://example.com/foo/") returns http://example.com
dirname("http://example.com/") returns http:
dirname("http://example.com") returns http:
So you have to be very carful which $_SERVER var you use and of course it works only for this specific problem. A much better general solution would be to use currentdir() on which basis you could use this to get the parent directory:
function parentdir($url) {
// note: parent of "/" is "/" and parent of "http://example.com" is "http://example.com/"
// remove filename and query
$url = currentdir($url);
// get parent
$len = strlen($url);
return currentdir(substr($url, 0, $len && $url[ $len - 1 ] == '/' ? -1 : $len));
}
Examples:
parentdir("http://example.com/foo/bar/index.php") returns
http://example.com/foo/
parentdir("http://example.com/foo/index.php") returns http://example.com/
parentdir("http://example.com/foo/") returns http://example.com/
parentdir("http://example.com/") returns http://example.com/
parentdir("http://example.com") returns http://example.com/
So you would have much more stable results. Maybe you could explain why you wanted to remove the trailing slash. My experience is that it produces more problems as you are not able to differentiate between a file named "/foo" and a folder with the same name without using is_dir(). But if this is important for you, you could remove the last char.
This example works with ports
function full_url($s)
{
$ssl = (!empty($s['HTTPS']) && $s['HTTPS'] == 'on') ? true:false;
$sp = strtolower($s['SERVER_PROTOCOL']);
$protocol = substr($sp, 0, strpos($sp, '/')) . (($ssl) ? 's' : '');
$port = $s['SERVER_PORT'];
$port = ((!$ssl && $port=='80') || ($ssl && $port=='443')) ? '' : ':'.$port;
$host = isset($s['HTTP_HOST']) ? $s['HTTP_HOST'] : $s['SERVER_NAME'];
return $protocol . '://' . $host . $port . $s['REQUEST_URI'];
}
$themeurl = dirname(dirname(full_url($_SERVER))).'/theme';
echo 'Theme URL';
Source: https://stackoverflow.com/a/8891890/175071
I'm with hek2mgl. However, just in case the script isn't always specifically 2 directories below your target, you could use explode:
$parts = explode("/",ltrim($_SERVER['SCRIPT_NAME'],"/"));
echo $_SERVER['HTTP_HOST'] . "/" . $parts[0];
As hek2mgl mentioned, it's correct, and a more dynamic approach would be dirname(dirname(htmlspecialchars($_SERVER['REQUEST_URI'])));.
EDIT:
$_SERVER['REQUEST_URI'] will omit the domain name. Referring #hek2mgl's post, you can echo dirname(dirname(htmlspecialchars($url)));
Here are useful commands to get the desired path:
( For example, you are executing in http:// yoursite.com/folder1/folder2/file.php)
__FILE__ (on L.Hosting) === /home/xfiddlec/http_docs/folder1/folder2/yourfile.php
__FILE__ (on Localhost) === C:\wamp\www\folder1\folder2\yourfile.php
$_SERVER['HTTP_HOST'] === www.yoursite.com (or without WWW)
$_SERVER["PHP_SELF"] === /folder1/folder2/yourfile.php
$_SERVER["REQUEST_URI"] === /folder1/folder2/yourfile.php?var=blabla
$_SERVER["DOCUMENT_ROOT"] === /home/xfiddlec/http_docs
// BASENAME and DIRNAME (lets say,when __file__ is '/folder1/folder2/yourfile.php'
basename(__FILE__) ==== yourfile.php
dirname(__FILE__) ==== /folder1/folder2
Examples:
*HOME url ( yoursite.com )
<?php echo $_SERVER['HTTP_HOST'];?>
*file's BASE url ( yoursite.com/anyfolder/myfile.php )
<?php echo $_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']; ?>
*COMPLETE current url ( yoursite.com/anyfolder/myfile.php?action=blabla )
<?php echo $_SERVER['HTTP_HOST'].$_SERVER["REQUEST_URI"];?>
*CURRENT FOLDER's URL ( yoursite.com/anyfolder/ )
<?php echo $_SERVER['HTTP_HOST'] . dirname($_SERVER['REQUEST_URI']); ?>
*To get RealPath to the file (even if it is included) (change /var/public_html to your desired root)
<?php
$cur_file=str_replace('\\','/',__FILE__); //Then Remove the root path::
$cur_file=preg_replace('/(.*?)\/var\/public_html/','',$cur_file);
?>
p.s.for wordpress, there exist already pre-defined functions to get plugins or themes url.
i.e. get plugin folder ( http://yoursite.com/wp-content/plugins/pluginName/ )
<?php echo plugin_dir_url( __FILE__ );?>

Categories