Welcome to the Question2Answer Q&A. There's also a demo if you just want to try it out.
+4 votes
2.0k views
in Q2A Core by
edited by

It is the first time that I need to get the URL of the calling plugin from within the qa-plugin.php

I have several days of coding behind me, so could be that I know the solution but forgot it.

What I found in my notes:

How to get website path / root and path to plugin

1. in layers:
$this->output('<link rel="stylesheet" type="text/css" href="'.QA_HTML_THEME_LAYER_URLTOROOT.'styles.css">');

2. in pages with ajax calls:
$itemIcon = '<img src="'.qa_path_absolute($this->urltoroot).'comment-icon.png" />';

3. in themes:
$theme_dir = dirname( __FILE__ ) . '/';
$theme_url = qa_opt('site_url') . 'qa-theme/' . qa_get_site_theme() . '/';

4. in plugin pages:
see $urltoroot:
    function load_module($directory, $urltoroot)
    {
        $this->directory=$directory;
        $this->urltoroot=$urltoroot;
    }

5. in qa-plugin.php ?? 

And especially within a custom function within the qa-plugin.php file?

Thanks for the help.

Q2A version: 1.7.4
by
Why do you need this in qa-plugin.php? That should only be for registering the plugins.
by
Because I have a function defined there that needs to access an image in the plugin folder. And I don't want to need to pass the plugin path from the plugin's page where I am calling the function.
by
I was in a quandary today ...

5 Answers

+3 votes
by
selected by
 
Best answer

At first, there will be a need to organize the kind of path. And, we should think these usage.

  1. Server file path
  2. Web page path (URI/URL)

Server file path

This is used to access from specific file to another file on the server.
  1. Absolute path: This is full address from server root to the specific folders and files.
    E.G: /home/(server_account)/[public_html/www]/([sub.]domain/)qa_plugin/(plugin folder)/qa-plugin.php
    Pre-defined constant: QA_BASE_DIR (Absolute installed path on the server [+ trailing slash])
    Pre-defined constant: QA_PLUGIN_DIR (QA_BASE_DIR+"qa-plugin/")

    Pre-defined constant: QA_THEME_DIR (QA_BASE_DIR+"qa-theme/")  etc
  2. Relative path: This is relative address from specific folder and file to another folder and file.
    E.G1: ../(another plugin folder)/qa-plugin.php
    E.G2: ./css/images/bg.jpg

Web page path (URI/URL)

This is used to access from specific page to another page on the web. Generaly, it is used in href/src attributes in HTML.

  1. Absolute path: This is full address to the specific page.
    E.G: http://([sub.]domain)/qa_plugin/(plugin folder)/qa-plugin.php
    Pre-defined function: qa_path_absolute() [Generate absolute path]
  2. Relative path: This is the address from specific page to another page.
    E.G1: questions
    E.G2: questions/../user/sama55
    Pre-defined function: qa_path() [Generate relative URI from current page]
    Pre-defined function: qa_path_html() [Generate sanitized relative URI from current page]
All constants and functions are defined in qa-base.php.
Hope this helps for Q2A beginners (not Kai).
+1 vote
by

I have done this in my way. Maybe there is a better way but it worked for me. I would glad if you have any better way and if you don't mind to share.

Here is the Gist link

 

/**
 * To set pluign path I used below
 *
 * Since my core class is in sub-directory of plugin, I had to point upward to get root directory
 */
define( 'Q2AM_DIR', q2am_trailingslash_dir( realpath( __DIR__ . '/../..' ) ) );


/*
 * To set pluign url
 * 
 * I have done bit it different way. Maybe this is not the best way
 * but it worked for me. If you find better way let me know
 */
$q2am_dir     = str_replace( [ '/', '\\' ], '/', Q2AM_DIR ); // this will gives pluign root directory
$plugin_dir = str_replace( [ '/', '\\' ], '/', QA_PLUGIN_DIR ); // this will give qa-plugin directory path

$path      = explode( '/', q2am_untrailingslash( $q2am_dir ) ); //Q2A Market function
$qa_plugin = explode( '/', q2am_untrailingslash( $plugin_dir ) ); //Q2A Market function
$key       = array_search( end( $qa_plugin ), $path );

if ( ( $key == array_search( end( $qa_plugin ), $path ) ) !== FALSE ) {
    $plugin_path = array_slice( $path, $key );
}

$q2am_url = implode( '/', $plugin_path );

// Finally, define the plugin url
define( 'Q2AM_URL', q2am_trailingslash( q2am_trailingslash( qa_opt( 'site_url' ) ) . $q2am_url ) );
by
Thank you. Looks complicated. I think if there is no easier way, I have to define it beforehand. However, this breaks the plugin when running on other sites... I hope Scott knows another solution. Thx!
by
Okay, but for other plugin you can just change the direcotry path and there you go. But anyway, I also prefer such thing in core.
by
Has this been added to the core? a way to get the root folder of Q2A or full plugin absolute url to plugin folder?
+2 votes
by
edited by

if(!function_exists('getMyPath')){
        function getMyPath($location) {
           $getMyPath = str_replace($_SERVER['DOCUMENT_ROOT'],'',$location);
           return $getMyPath;
        }
}

Then

$myUrl = getMyPath(__DIR__)."/";

UPDATED (MORE STABLE)

//get absolute URL of any known folder

if(!function_exists('getMyPath')) {
  function getMyPath($location)
  {
    $location = QA_BASE_DIR . $location;
    // not using QA_PLUGIN_DIR , //for flexibility sake
    $getMyPath = str_replace($_SERVER['DOCUMENT_ROOT'], '', $location);
    return $getMyPath;
  }
}

//usage
getMyPath("myExtra/css/main.css");
getMyPath("otherExtra/js/main.js");
by
failed when on Windows localhost, apache (local system)
See update
+1 vote
by
edited by

To get the plugin path / URL (and your q2a forum runs not in a subfolder) you can use: 

$pathtome = '/qa-plugin/'.basename(__DIR__).'/qa-plugin.php";

or like in my scenario getting an image file: 

$pathtome = '/qa-plugin/'.basename(__DIR__).'/img/icon.png";

The '/qa-plugin/' will always go to the root and then into the plugin folder. 

by
Has a dangerous assumption that q2a is the root of the web server, no?
by
Yes, no subfolder. Thanks for pointing out for others!
+2 votes
by

You actually have the directory and urltoroot variables already defined in the global context. As the qa-plugin.php is actually part of the global context then you can make use of the global variables, which are defined immediately before the execution of the qa-plugin.php file: $qa_plugin_directory and $qa_plugin_urltoroot. They already contain the needed values because they are actually the ones that feed all plugin modules and layers with those values so they are pretty much ready to use.

Having said so, bear in mind it is a bad practice to add code to this file as that code gets executed in every request. The less code you have in the qa-plugin.php file the better.

by
When I call:    var_dump($qa_plugin_urltoroot); in the qa-plugin.php I get the URL-relative-path to the folder. However, when I am calling this in a function within the qa-plugin.php, I get undefined. I used global $qa_plugin_urltoroot; inside the function, then I get an empty string?!
by
That's why global variables are not good (and they're all around the core). If you add a function that gets called at plugin load time it will work for sure. The thing is that if you call your global function, which "calls in" the global variables and that function is executed AFTER another plugin has registered then they will have a different value. If you call that function AFTER all plugins have been registered then the value will be null (it is nulled after initialization).

Anyway, if you're looking to create reusable functions then you could create a Utils class and require it in qa_plugin.php. That class could have static functions. Same effect, keeps the global context as clean as possible and is much better modularized.
...