We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 39251
    • 53 Posts
    I have a really tight deadline on this, so any ideas, no matter how crazy, I'm open to.

    I have a site (Revo 2.2.0) where admins have entered a bunch of listings (resources). Users can register on the site (I'm using Login) and be made "owner" (set in a template variable) of those listings by the admins. A registered user can add new listings, and edit and delete listings they own. I'm using Newspublisher for this, so far. All additions/changes/delete requests must be moderated by site admins, and no changes are to be made on the live website until approved. (Admins will be notified of additions and changes by ResourceWatcher.)

    Admins will be using only the MODx admin interface, users will be using only the front-end Newspublisher interface. I'll hand-code whatever is necessary, I'm just trying to figure out the best way to handle this.

    Adding is easy. I just make new listings unpublished. The admin simply has to review the listing and then publish it (or not). (I had to do a slightly bizarre hack to a Newspublisher template using an uncached snippet to automatically set the owner to the current user, but it works...)

    Deleting is easy enough. I've created a template variable that will be set to true if a user requests to delete the listing. The admin either deletes the listing, or sets that variable back to false if they don't want it deleted for whatever reason.

    Editing is where I'm stuck. Easy would be to simply unpublish a resource if a user edits it. However the client wants the old version of the published resource to continue to display on the site until the edits are approved, and they want to be able to compare the original information with the user's changes before approving them.

    Each listing is pretty much the pagetitle and a long list of template variables. One solution I've thought of is to duplicate each template variable the user can edit, and use the duplicated set to store the edits. Then use some kind of back-end code that runs when the admin approves the changes that copies the edits over the original values. Clunky, but I think it will work...

    But I've been looking at add-ons wondering if there's some kind of alternate way to do this. I've found VersionX2, although it sounds like I'd have to hack it to work as the client wants, so that the most recent changes aren't displayed on the live site. But at least it does take care of the problem of storing edits. There's Group Edit which, well, seems to be in Russian, but "Component for group editing of resources" could help. There's MIGX which, well, frankly I'm not sure exactly what it does by reading it, but it could be useful. smiley

    I've also thought of other ideas, like creating completely new resources when a user edits an existing one, or storing all user edits as a JSON string in a single TV and dealing with them in the admin resource editor, but I haven't come up with anything I really like.

    Oh, the final bit of difficulty is that this is a live site, so I have to do all of my experimenting without breaking anything, or clone this monster site somewhere else to experiment...

    So... thoughts?
      If there's a better way to do it, I'll find it.
      • 3749
      • 24,544 Posts
      I don't know of a good solution. I would have thought VersionX would do it.

      One solution (admittedly not great) would be to write a plugin that prepends an 'X' to the pagetitle and alias only for those users and saves it as a new, unpublished page. The admin could delete the original and change the pagetitle and alias. At least you wouldn't be hacking the core, and in theory, you could create a CMP to manage the conversion. I think you'd lose the createon date unless the plugin transferred it.

      There's probably a better solution, but I can't think of one right now.


      ------------------------------------------------------------------------------------------
      PLEASE, PLEASE specify the version of MODX you are using.
      MODX info for everyone: http://bobsguides.com/modx.html
        Did I help you? Buy me a beer
        Get my Book: MODX:The Official Guide
        MODX info for everyone: http://bobsguides.com/modx.html
        My MODX Extras
        Bob's Guides is now hosted at A2 MODX Hosting
        • 28042 ☆ A M B ☆
        • 24,524 Posts
        It might be easier to make the resources static, then manage the files. All that's in the database is the path to the file.

        A front-end editor would just open the file in a form, then email the moderator (formit might be good for this). The editor can be styled to match the page that's being edited.

        Then the moderator would have a utility resource that he edits to load and preview the new file. A plugin would be able to rename the old file to backup, and rename the new file to the old file name, thus "publishing" the new file. The plugin could also set the editedon date. It would only be triggered if the utility resource is saved with a specific value in one of the fields; perhaps even a checkbox TV with "Approved".

        The directory structure could be arranged to match the usernames, adding organization and control.
          Studying MODX in the desert - http://sottwell.com
          Tips and Tricks from the MODX Forums and Slack Channels - http://modxcookbook.com
          Join the Slack Community - http://modx.org
          • 39251
          • 53 Posts
          The way we've currently gotten this kind of working is to have two copies of each TV. One contains the value from when the admin last saved the resource, the other is either identical or contains updates made by users on the front end.

          When an admin views a resource, if the two values are different, it puts the user's updated value in the field and the original value is displayed below the field, for reference. When the admin saves the resource again, each TV is updated (in OnBeforeDocFormSave) so that the values match again.

          Problem is that this isn't refreshing the resource editor, so it's still showing that the values don't match. How do I get it to refresh the resource editor when the admin saves?

          (I'm hoping to come back here eventually and describe some brilliant way I solved the problem, but right now, we're in the "let's just get SOMETHING working" mode...)
            If there's a better way to do it, I'll find it.
            • 3749
            • 24,544 Posts
            That's actually pretty brilliant. Does it work if you reload the page after saving?

            If you're doing it in a plugin, try using one or both of these:

            $modx->reloadContext('web');


            $cm = $modx->getCacheManager();
            $cm->refresh();


            ------------------------------------------------------------------------------------------
            PLEASE, PLEASE specify the version of MODX you are using.
            MODX info for everyone: http://bobsguides.com/modx.html
              Did I help you? Buy me a beer
              Get my Book: MODX:The Official Guide
              MODX info for everyone: http://bobsguides.com/modx.html
              My MODX Extras
              Bob's Guides is now hosted at A2 MODX Hosting
              • 39251
              • 53 Posts
              Yes, everything works perfectly behind the scenes. You never know what will happen when panic and desperation kick in. smiley

              Having some weird results with these events, though. I'd said I was changing the TVs in OnBeforeDocFormSave, but when I took out some code that had been popping up a message in $modx->event->output(), the tv save quit working. It was like not having the pop-up wasn't giving it time to run my code.

              So I moved the TV updating to OnDocFormSave, but if it wasn't still updating the TVs (which it is), I'd be convinced that wasn't dong anything. Neither of your suggestions above have any effect, $modx->event->output() doesn't do anything. The only thing I can put in there that seems to have ANY effect is a die, which then just keeps the save pop-up displaying until I manually refresh.

              I also have code in this plug-in that writes every event that MODx fires to a text file. That doesn't even output anything on a form save. There's something really odd (or at least that I don't understand) about how these events are firing.
                If there's a better way to do it, I'll find it.
                • 39251
                • 53 Posts
                Helping myself absolutely none, I learned that my file-writing code doesn't work when you save a plug-in, either. (I just made a plug-in that writes EVERY event to a text file as they occur. Yes, I debugged it carefully. I hate having to manually clear caches...)

                So when you change a template, it fires the events just as when you load a page. That is triggered in templateWarning() in /manager/assets/modext/widgets/resource/modx.panel.resource.js.

                Right above that is a beforeSubmit() that fires when you hit save and a success() which fires after it saves. I can edit THAT function and add:
                location.href = location.href;
                return;
                

                right after the part where it commits the changes (before it refreshes the tree). That seems to do everything it needs to do to save the changes, flashes the success messages, and then refreshes the page (although unfortunately you can't tell it's trying to refresh the page unless you notice the browser is reloading).

                Anyway, while that works, I have this bad feeling that's probably not what I really want to be doing...
                  If there's a better way to do it, I'll find it.
                  • 39251
                  • 53 Posts
                  Here's where the last 4.5h of my life went:
                    case 'OnDocFormPrerender':
                  
                  $script = <<<EOD
                  <script type="text/javascript">
                  // <![CDATA[
                  
                  Ext.onReady(function() {
                    var panel = Ext.getCmp("modx-panel-resource");
                    if (panel) {
                      panel.removeListener('success', panel.success);
                      panel.on('success', function(e){
                        var g = Ext.getCmp('modx-grid-resource-security'); // From modx.panel.resource.js
                        if (g) { g.getStore().commitChanges(); } // From modx.panel.resource.js
                        MODx.msg.status({ title: _('success'), message: _('save_successful') + ' Reloading Page...', dontHide: true});
                        location.reload(true);
                        return false;
                      });
                    }
                  });
                  // ]]>
                  </script>
                  EOD;
                      $modx->controller->addHtml($script);
                      break;
                  


                  I have yet to find proof that ExtJS actually makes things easier for programmers...

                  P.S. This is going to run for every page, not just the ones I'm specifically targeting. And I don't want it running on resource adds. Obviously I need an "if" statement in there when my brain starts working again... (That would not be tonight.)

                  Edit: Ok, one thing. Add this at the top of the plug-in so it doesn't break anything when you're creating a new resource:
                  // Make sure we are in the mgr context
                  if ($modx->context->get('key') != 'mgr') return;
                  
                  // Only run on resource edits
                  if (!isset($scriptProperties['resource'])) return;
                  
                  [ed. note: ocdcoder last edited this post 14 years, 2 months ago.]
                    If there's a better way to do it, I'll find it.
                    • 3749
                    • 24,544 Posts
                    It looks good to me, though I don't claim to be an expert on ExtJs.



                    ------------------------------------------------------------------------------------------
                    PLEASE, PLEASE specify the version of MODX you are using.
                    MODX info for everyone: http://bobsguides.com/modx.html
                      Did I help you? Buy me a beer
                      Get my Book: MODX:The Official Guide
                      MODX info for everyone: http://bobsguides.com/modx.html
                      My MODX Extras
                      Bob's Guides is now hosted at A2 MODX Hosting
                      • 39251
                      • 53 Posts
                      Thanks. smiley The only time I've ever used it is when I'm trying to make MODx do something it doesn't want to do. I'm generally really desperate if I'm to this point. I understand it about as well as I do Latin...
                        If there's a better way to do it, I'll find it.