Giter Club home page Giter Club logo

Comments (22)

axelitus avatar axelitus commented on August 23, 2024

I've found a solution for this issue which I think doesn't interfere with how things are supposed to work:

public static function find_file($directory, $file, $ext = '.php', $multiple = false, $cache = true)
{
    $cache_id = '';
    $ns = '';

    $paths = static::$_paths;

    // get extra information of the active request
    if (class_exists('Request', false) and $active = \Request::active())
    {
        $cache_id = md5($active->uri->uri);
        $paths = array_merge($active->paths, $paths);
    }

    // the file requested namespaced?
    if($pos = strripos(ltrim($file, '\\'), '\\'))
    {
        $file = ltrim($file, '\\');
        $ns = ucfirst(substr($file, 0, $pos));

        // get the namespace path
        if ($path = \Autoloader::namespace_path('\\'.$ns))
        {
            // and strip the classes directory as we need the module root
            $paths = array(substr($path,0, -8));

            // strip the namespace from the filename
            $file = substr($file, $pos+1);
        }
        $ns .= DS;
    }

    $path = $directory.DS.strtolower($file).$ext;

    if (static::$path_cache !== null and array_key_exists($cache_id.$ns.$path, static::$path_cache))
    {
        return static::$path_cache[$cache_id.$ns.$path];
    }

    $found = $multiple ? array() : false;
    foreach ($paths as $dir)
    {
        $file_path = $dir.$path;
        if (is_file($file_path))
        {
            if ( ! $multiple)
            {
                $found = $file_path;
                break;
            }

            $found[] = $file_path;
        }
    }

    if ( ! empty($found))
    {
        $cache and static::$path_cache[$cache_id.$ns.$path] = $found;
        static::$paths_changed = true;
    }

    return $found;
}

from core.

WanWizard avatar WanWizard commented on August 23, 2024

This was already on my todo list. I also want to add the possibility to use fully qualified filename.
I'll have a look at it over the weekend.

from core.

axelitus avatar axelitus commented on August 23, 2024

Fine! In the meantime I'll stick with my patch... it works for me now! :)

from core.

axelitus avatar axelitus commented on August 23, 2024

Is this if supposed to be empty? or even there?
https://github.com/fuel/core/blob/develop/classes/fuel.php#L275

Also this breaks everything if the file wasn't found:
https://github.com/fuel/core/blob/develop/classes/fuel.php#L311

from core.

axelitus avatar axelitus commented on August 23, 2024

I'm sorry I keep re-opening this issue but it's not completely fixed. Well we have namespaces but there's an issue which was introduced by this, which is posted in the forums:

I debugged it today and narrow it down to the find_file() function. As of now the master branch has still a line of code which was used for testing purposes I think in file fuel.php L311 which prevents from showing anything, not even an error. But what's happening is this:

When an exception/error occurs Fuel calls an error view, which is located in core/views/errors/ folder. When this is called then the function gets called liked this:

\Fuel::find_file('views', 'errors\php_fatal_error', '.php', false, false);

The first test that is made is if the targeted file was requested using absolute path; the second one (more interesting due to the nature of this issue) is to see if the file requested was namespaced L244:

// the file requested namespaced?
elseif($pos = strripos(ltrim($file, '\\'), '\\'))

running that command with the given arguments will get the file misinterpreted as being namespaced so everything will be messed-up and that's why the Error reporting is broken in the master and develop branches because it searches for a namespaced file which is interpreted as being in a module called 'errors' and not a directory into the views directory.

Don't know what's best to fix this... if leaving the function as it is and making the call like:

\Fuel::find_file('views\errors', 'php_fatal_error', '.php', false, false);

which will need to change the function call... or change the find_file() function's behavior.

from core.

axelitus avatar axelitus commented on August 23, 2024

The error originates from this line of code in the error.php file in core/classes. This is what gets called:

exit(\View::factory('errors'.DS.'php_fatal_error', $data, false));

The DS constant is an '' so this will effectively turn into 'errors\php_fatal_error' which worked in the previous version of the find_file() function... but as namespaces were introduced then this doesn't work anymore as it is confused for a namespace called 'errors'.

from core.

axelitus avatar axelitus commented on August 23, 2024

I've come up with a really horrible workaround so that the function works as intended with namespaces and error views...
Note beforehand: I really don't like this! Don't judge hehe... but this way let's me debug other code easier...

On line #245 change this:

elseif($pos = strripos(ltrim($file, '\\'), '\\'))

for this:

elseif($directory !== 'views' && $pos = strripos(ltrim($file, '\\'), '\\'))

Awful I know... but it's only a temporary workaround...

from core.

jschreuder avatar jschreuder commented on August 23, 2024

I'm having the same problem but as the current code still looks unfinished I'll wait for WanWizard to look into this for a real solution.

In the mean time I think my ugly fix is better than yours :P

Add after line 259 - https://github.com/fuel/core/blob/master/classes/fuel.php#L259

else
{
    $paths = static::$_paths;

    // get extra information of the active request
    if (class_exists('Request', false) and $active = \Request::active())
    {
        $cache_id = $active->uri->uri;
        $paths = array_merge($active->paths, $paths);
    }
}

In words: when the namespacing fails, just do what would happen otherwise.

from core.

axelitus avatar axelitus commented on August 23, 2024

Hehe, yes it 'looks' nicer but it doesn't work, as the failure is because the path to the error files IS identified as a namespaced filename... so it really never reaches your ugly fix :P haha... sorry, I mislooked the line you meant... it indeed is a better fix, it's more generic as mine... I'll implement this fix into my repo...

And yes... let's see how WanWizard fixes this... but it involves not only programming I think... so it could take some time before this one is fixed sigh... in the meantime I'll stick with my horrible patch I'll use your ugly patch as I need to be able to debug my code, and this error screen helps A LOT!

from core.

WanWizard avatar WanWizard commented on August 23, 2024

Back online!

We need to think about the best way to approach this issue:

  • have it fall through if no valid module namespace has been found
  • use something else then a single backslash to identify the module name

Suggestions welcome

from core.

axelitus avatar axelitus commented on August 23, 2024

As posted here I suggest a pipe to separate namespace names from file names...

Regarding the way that Config::save() handles the saving process, I enumerate some points here; that's what I have implemented (of course there's the issue still pending about knowing when it is a namespace, as of now I use the same find_file() method of looking for a backslash...)

from core.

WanWizard avatar WanWizard commented on August 23, 2024

Decided to choose for a fall-through. It means that on Windows platforms, some extra code is executed as paths will always contain a backslash. So be it.

I'm not in favor of alternative random characters, it will only confuse people.

from core.

jschreuder avatar jschreuder commented on August 23, 2024

Wouldn't it for consistancy sake be better if we got this to work the same on *nix & Windows?

This was originally my oversight as I proposed the "namespaced path" solution, so I feel a bit responsible. I think it might be better if we would handle the first segment of a path as a module identifier (to be determined by either forward or backward slash) and have the module path prefixed on any type of system to the full array of paths.

That way Fuel will behave the same on both *nix & windows platforms.

from core.

WanWizard avatar WanWizard commented on August 23, 2024

jschreuder: I can live with that, but it means a namespace check for every call to find_file(). Which due to the number of calls could be causing a noticable delay.

from core.

jschreuder avatar jschreuder commented on August 23, 2024

WanWizard: you have a point there, though the overhead should be very small as it's only a call to the \Autoloader::namespace_path() which shouldn't be noticeable as it only checks the array for a key?

Another operator we could use might be ::, though that'd only a little less random than using pipes.

from core.

axelitus avatar axelitus commented on August 23, 2024

But wouldn't that way (take the first segment of a path as a module) interfere with the global APPATH? I mean that it would prevent of having sub-folders inside the APPATH, because it will always take the first segment as a module.

Unless maybe if we want to use subfolders in the APPATH folder then we could use a (to be defined: backslash or forwardslash) as the first character in the $file parameter... that way we are stating that all that comes next is a directory structure relative to the APPATH folder.

To sum up:

Referencing modules:

find_file('views', 'mymodule\subfolder1\subfolder2\filename', '.php', [...]);

Referencing the APPATH folder:

find_file('views', '\subfolder1\subfolder2\filename', '.php', [...]);

I agree with jschreuder that :: it's more natural than using a pipe... however, it still can confuse people...

from core.

jschreuder avatar jschreuder commented on August 23, 2024

Reread my proposal:

I think it might be better if we would handle the first segment of a path as a module
identifier (to be determined by either forward or backward slash) and have the
module path prefixed on any type of system to the full array of paths.

from core.

WanWizard avatar WanWizard commented on August 23, 2024

Just thought of another downside:

Suppose you have a module called 'test', and load something like 'test/this/that'. This means that find_file() will only check the module, and you can't have for example an app view called 'test/this/that.php'.

from core.

axelitus avatar axelitus commented on August 23, 2024

That is what I meant, just not only specific to views...

That's why I proposed prefixing with a slash if one does not mean to use module names...

'test/this/that' will be interpreted as $module = 'test'; $file = 'this/that';

whereas

'/test/this/that' will be interpreted as-is inside the APPATH thus
$module = APPATH (or global); $file = 'test/this/that'

so you could have a view named 'test/this/that.php'

I think this could work, but I really don't know the core of Fuel that much and how 'every' call to files is made, so perhaps I'm missing something here...

from core.

axelitus avatar axelitus commented on August 23, 2024

It would be also helpful to define either forward-slash or backward-slash to separate folder structure and then internally change the defined char to DS (as DS changes from *nix to Windows)...

This would insert an extra function call and it may not be needed in some cases as the selected char would match to the filesystem separator; but it would ensure that no matter where the code is running it would work as expected. There's a point where convenience supersedes performance...

from core.

jschreuder avatar jschreuder commented on August 23, 2024

I've repeated this already, but I will again - this time even shorter and to the point:

and have the module path prefixed [...] to the full array of paths.

from core.

WanWizard avatar WanWizard commented on August 23, 2024

Decided to ignore this... ;)

Using the first path segment as a namespace identifier causes the namespace to allways be selected if found, so you can never have a folder name equal to an existing namespace (for example, you can not load a view called 'auth/login' anymore if you have loaded the auth package).

Opted instead of using the double colon to identify the namespace: find_file('views', 'module::folder/file');

from core.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.