• Flexible media resource path#

  • pepebe Reply #1, 3 months, 2 weeks ago

    Reply
    I'm thinking about somthing like document specific media resource folders.

    The idea is to have an individual folder for each document ID. How they are created isn't the toppic of this post, let's asume they are already here.

    The structure goes like this:

    assets/ID/000/
                         00/
                             1 -> ID: 1 -> assets/ID/000/00/1
                             2 -> ID: 2 -> assets/ID/000/00/2
                             ...
                         10/
                         20/
                            1 -> ID: 21 -> assets/ID/000/20/1
                            2 -> ID: 22 -> assets/ID/000/20/2
                            ...
                         ...
    assets/ID/100/
    assets/ID/200/
    assets/ID/...
    


    If you extend this system to 4 digits, you can easily handle 9999 documents.

    Admittedly this is an awful lot of clicking but with the introduction of media resources in REVO 2.2 you can set a base_path and a base_url for specific resources. This makes things much easier. Now it takes only three clicks to navigate to the correct folder.

    Heres my question: How can I hack the media resources system to automatically open the document-specific folder?

    Adding a snippet to the base_path and base_url parameters doesn't seem to work,

    assets/img/ID[[!pathToDocFolder]]


    The snippet doesn't seem to be parsed and as a result the path is broken.

    So what comes next. Can the media resource system be enhanced by a plugin, do I have to hack the core?

    Please share your thoughts.

    Regards,

    pepebe






  • Bruno17 Reply #2, 3 months, 2 weeks ago

    Reply
    see this post for an example, how you can process snippets in media-pathes:

    http://forums.modx.com/thread/73966/combo-browser-source-param-how-do-i-set-basepath-in-2-2#dis-post-410712


  • pepebe Reply #3, 3 months, 2 weeks ago

    Reply
    @Bruno: Thanks. That's right on target. You are beating google and the forum search function in 11 out of 10 cases. Hope you don't mind but I had to send you a PM.


  • pepebe Reply #4, 3 months, 2 weeks ago

    Reply
    Got it nearly working (90%).

    I've added a snippet to generate the path:

    <?php
    /* documentResourcePath Snippet                                               */
    /* Returns a path string depending on the id of the current resource */
    /* Example: 0000/100/20/0/ = 120                            */
    
    $docID = $modx->resource->get('id');
    
        $maxDocs        = 9999;
        $maxKey         = count( str_split( $maxDocs ) ) - 1;
        
        $digits         = str_split( $docID );
        $numberOfDigits = count( $digits );
    
        /* mirrow array */
        $digits = array_reverse($digits);
        
        /* add missing key/value pairs to the array */
        for( $key=0; $key <= $maxKey ;$key++ ){
            if( !array_key_exists( $key, $digits ) ) {
                $digits[$key] = "0";
            }
        }
    
        /* mirrow again */
        $digits = array_reverse($digits);
    
        /* add trailing zeros to array values */
        foreach( $digits as $key => $value ) {
            $suffix = "";
            for( $i=$key; $i < $maxKey; $i++ ) {
    	    $suffix .= "0";
            }
          $digits[$key] = $value.$suffix."/";
        }
    
        $docResourcePath = "";
        
        /* combine all values to a path*/
        foreach ( $digits as $key => $value ){
            $docResourcePath .= $value;
        }
    
        return $docResourcePath;
    


    Next I...
    * installed your processMediaPath plugin.
    * checked the OnMediaSourceGetProperties event
    * added a new media resource "document specific image path"
    * added a new property "processPath" to that media resource
    * and finally added "assets/images/[ [documentResourcePath] ]" to the media resource basePath and baseUrl properties.

    Debug tells me the plugin is calculating the correct path information. BUT the path values are not updated.

    $modx->event->output($modx->toJson($params));


    Is something wrong with that particular line?


  • Bruno17 Reply #5, 3 months, 2 weeks ago

    Reply
    not in all situations where onMediaSourceGetProperties is fired, there is a modx-resource-object.

    here is a modified version of the plugin, which may also not work in all situations, but I think its a start:

    if (!function_exists('processMediaPathes')) {
        function processMediaPathes($path)
        {
            global $modx;
            $chunk = $modx->newObject('modChunk');
            $chunk->setContent($path);
            $chunk->setCacheable(false);
            return $chunk->process();
        }
    }
    
    
    switch ($modx->event->name) {
        case 'OnMediaSourceGetProperties':
    
            $sourceUpdateActionID = 0;
            if ($object = $modx->getObject('modAction', array('namespace' => 'core', 'controller' => 'source/update', ))) {
                $sourceUpdateActionID = $object->get('id');
            }
    
            $params = $modx->fromJson($scriptProperties['properties']);
            // don't manpulate-path if updating mediasource
            if (empty($params['processPath']) || $_REQUEST['a'] == $sourceUpdateActionID) {
                $modx->event->output($scriptProperties['properties']);
                return;
            }
    
    
            //$path = $params['basePath']['value'];
            //$modx->parser->processElementTags('',$path,true,true);
            if (!is_Object($modx->resource)) {
                //try to get the actual resource out from HTTP_REFERER
                $parsedUrl = parse_url($_SERVER['HTTP_REFERER']);
                parse_str($parsedUrl['query'], $parsedQuery);
                if (isset($parsedQuery['amp;id'])) {
                    $parsedQuery['id'] = $parsedQuery['amp;id'];
                }
                if (isset($parsedQuery['id'])) {
                    $modx->resource = $modx->getObject('modResource', $parsedQuery['id']);
                }
            }
    
            $params['basePath']['value'] = processMediaPathes($params['basePath']['value']);
            $params['baseUrl']['value'] = processMediaPathes($params['baseUrl']['value']);
    
            $modx->event->output($modx->toJson($params));
    
            $debug['http_referer'] = $_SERVER['HTTP_REFERER'];
            $debug['parsedUrl'] = $parsedUrl;
            $debug['parsedQuery'] = $parsedQuery;
    
            $debug['basePath'] = $params['basePath']['value'];
    
    
            $chunk = $modx->getObject('modChunk', array('name' => 'debug'));
            $chunk->setContent($chunk->get('snippet') . print_r($debug, 1));
            $chunk->save();
    
            break;
    }
    return;
    


    in your snippet you should also check, if modx-resource is an object before using its functions

    and dont forget to create the mediasource-property 'processPath' and set its value to 1


  • pepebe Reply #6, 3 months, 2 weeks ago

    Reply
    Update: I've switched over to Bruno17 new script but at first it didn't work out. I really tried to find the culprit but in the end I gave up (learned a view things along the way about the MODX API ). In the end I gave up on the whole topic and switched over to other things.

    A couple of minutes ago I updated a document and suddenly it worked like a charm. Caching? JS? I have no clue, but I'm happy

    Thnks for your great support Bruno17!

    Regards,

    pepebe



  • pepebe Reply #7, 3 months, 2 weeks ago

    Reply
    Another Update:

    I just realized that my snippet only works if you are working with resources that are properties of the document that is send to the browser.

    If you are grabbing content from another document (for example using the docid parameter of the MIGX getImageList snippet), the link will be broken because the path to the resource is build for the current resource and not for the document that is the "owner" of the resource.

    I'm trying to fix that issue.

    Regards,

    pepebe



  • pepebe Reply #8, 3 months ago

    Reply
    If have mangeged to solve the problem with mixed document ids. It more of a hack than an actual solutuion but it works.

    Whats bothering me is the fact that using processMediaPathes and documentResourcePath to create document specific images pathes is EXTREMELY slowing down things.

    Example:

    A wayfinder over two levels and approx. 50 items takes uncached about 0.2 seconds.
    The same wayfinder call picking up image tv along the way takes about 26 seconds.

    Thats about 100 times more!

    For further research I have used an empty chunk instead of my snippet.

    assets/img/ID/. Then I cleareed the cache and reloaded the testpage but that didn't change anything.

    Does anyone here have first-hand experience that indicates that flexible resource pathes?

    Regards,

    pepebe



  • pepebe Reply #9, 3 months ago

    Reply
    If have mangeged to solve the problem with mixed document ids. It more of a hack than an actual solutuion but it works.

    Whats bothering me is the fact that using processMediaPathes and documentResourcePath to create document specific images pathes is EXTREMELY slowing down things.

    Example:

    A wayfinder call over two levels and approx. 50 items takes uncached about 0.2 seconds.
    The same wayfinder call picking up image tv along the way takes about 26 seconds.

    Thats about 100 times more!

    For further research I have used an empty chunk instead of my snippet.

    assets/img/ID/[$emptyChunk]

    Then I cleareed the cache and reloaded the testpage but that didn't change anything.

    Does anyone here has first-hand experience with manipulating media resouce pathes?

    As a temprary fix it would be nice to switch-off the path on the frontend side. I have tried varius output options, but to no avail.

    Example:

    Instead of assets/img/ID/0000/000/00/1/galery/example.jpg I would like to have just galery/example.jpg.

    I could easily add the relevant path information with my snippet...

    Regards,

    pepebe


  • pepebe Reply #10, 2 months, 4 weeks ago

    Reply
    Some further data:

    The problem not only applies to wayfinder calls but also to getResourceField.

    get image TV with getResourceField
    [[!Executioner? 
       &tElementClass=`modSnippet` 
       &tElement=`getResourceField`
       &tEcho=`comment`
          &id=`27` 
          &field=`nav248` 
          &processTV=`1` 
          &default=`Sorry, no data available`
          &docid=`27` 
    ]]
    


    Executioner Snippet
    Document: test_mediapath (ID:143)
    modSnippet: getResourceField
    Execution time:0.5957 s

    get Pagetitle with getResourceField
    [[!Executioner? 
       &tElementClass=`modSnippet` 
       &tElement=`getResourceField`
       &tEcho=`comment`
          &id=`27` 
          &field=`pagetitle` 
          &default=`Sorry, no data available`
          &docid=`27` 
    ]]
    

    Executioner Snippet
    Document: test_mediapath (ID:143)
    modSnippet: getResourceField
    Execution time:0.0053 s

    0.0053 vs. 0.5957 seconds. Also 100x slower.