12 Replies Latest reply on Oct 22, 2008 12:07 PM by (Glennyboy)

    Delete Folder with all Subfolders and files

    Level 1
      Hi
      This is driving me crazy....

      I have a record delete transaction and have linked a delete folder transaction to it. On delete the record deletes fine, but the folder simply wont delete if there are sub-folders below it.

      This is my delete folder transaction:-

      //start Trigger_DeleteFolder trigger
      //remove this line if you want to edit the code by hand
      function Trigger_DeleteFolder(&$tNG) {
      $deleteObj = new tNG_DeleteFolder($tNG);
      $deleteObj->setBaseFolder("../extranet/files/");
      $deleteObj->setFolder("{ClientID}");
      return $deleteObj->Execute();
      }

      I'm initially uploading a file to a dynamic directory three levels below the base folder and have already set the CHMOD on files and directories to 0777 in KT_config.inc.php so I don't think permissions are the problem. It just seems that the delete folder server behaviour wont delete a specific folder if there are = sub-folders + any files below it. It works fine if there is just one target folder.

      Can anyone advise how to ensure that all sub-folders are also deleted?

      Thanks

      Glennyboy
        • 1. Re: Delete Folder with all Subfolders and files
          Günter Schenk Level 4
          Hi Glennboy,

          -------
          It just seems that the delete folder server behaviour wont delete a specific folder if there are = sub-folders + any files below it. It works fine if there is just one target folder.
          -------

          I can confirm this. Way back when ADDT´s predecessor "MX Kollection" was developed, recursive deletion has in fact not been implemented, and this hasn´t changed ever since.

          --------
          Can anyone advise how to ensure that all sub-folders are also deleted?
          --------

          Maybe you could do that with a Custom Trigger that´s set to BEFORE and will first delete all files and folders located within the main folder ? Please google for "php delete recursive" to get some pointers respectively code examples.

          Cheers,
          Günter Schenk
          Adobe Community Expert, Dreamweaver
          • 2. Re: Delete Folder with all Subfolders and files
            Level 1
            Hi Günter

            I tried the Trigger BEFORE and unfortunately that didn't work.

            I would have thought this was a pretty important transaction and it seems weird that Adobe has not addresses this. Can anyone provide a workaround?

            Glennyboy
            • 3. Re: Delete Folder with all Subfolders and files
              Günter Schenk Level 4
              Hi Glennboy,

              what exactly did not work ? Did the trigger not execute at all, or did it execute, but no folders/files were deleted from the directory you specified ?

              -------
              I would have thought this was a pretty important transaction and it seems weird that Adobe has not addresses this
              -------

              well, it´s really not Adobe´s fault now, as this sort of behaviour (not deleting subfolders) was decided on when Interakt was still an independant company.

              Cheers,
              Günter Schenk
              Adobe Community Expert, Dreamweaver
              • 4. Re: Delete Folder with all Subfolders and files
                Level 1
                Hi again Günter

                I tried the trigger before and after the delete record trigger and both times it deleted the record fine, but not the folder + sub folders. However testing in IE I did get the full error response:-

                Error:
                Error deleting folder. Server error is: Error deleting folder.
                Developer Details:
                Error deleting folder. Server error is: Error deleting folder "/home/brandd/public_html/extranet/files/41/9". Permissions not granted. (FOLDER_DEL_ERROR)
                tNG Execution Trace - VIEW
                tNG_delete.executeTransaction
                STARTER.Trigger_Default_Starter
                tNG_delete.doTransaction
                BEFORE.Trigger_Default_saveData
                tNG_delete.saveData
                tNG_delete.prepareSQL
                tNG_delete.executeTransaction - execute sql
                AFTER.Trigger_DeleteFolder*

                41 being the ID that I am using and naming the folder to be deleted after.

                Now I thought that as all the related folders were set to CHMOD 777 it wouldn't be a permissions issue, but it seems it could be?

                Glennyboy
                • 5. Re: Delete Folder with all Subfolders and files
                  Günter Schenk Level 4
                  Hi Glennboy,

                  -------
                  I tried the trigger before and after the delete record trigger
                  -------

                  1. what custom PHP code does your trigger contain ?

                  2. the idea is to try using a Custom Trigger to *first* delete all files & folders which are located *within* the folder named "41", and once this folder has been successfully emptied, have ADDT´s regular DeleteFolder trigger delete the folder "41" itself -- that´s why such a Custom Trigger will have to executed first.

                  Cheers,
                  Günter Schenk
                  Adobe Community Expert, Dreamweaver
                  • 6. Re: Delete Folder with all Subfolders and files
                    Level 1
                    Hi Gunter

                    OK so I've added a recursive_remove_directory custom transaction to trigger before the record is deleted and the delete folder transaction. It would work if not for the fact that I can't pass my ClientID (from recordset RsClients on the page to the trigger (as I could with the ADDT Delete folder). Here are the transactions:-

                    //start Trigger_DeleteFolder trigger
                    //remove this line if you want to edit the code by hand
                    function Trigger_DeleteFolder(&$tNG) {
                    $deleteObj = new tNG_DeleteFolder($tNG);
                    $deleteObj->setBaseFolder("../extranet/files/");
                    $deleteObj->setFolder("{ClientID}");
                    return $deleteObj->Execute();
                    }
                    //end Trigger_DeleteFolder trigger

                    //start Recursive_Remove trigger
                    function Recursive_Remove(&$tNG) {
                    function recursive_remove_directory($directory, $empty=FALSE)
                    {
                    if(substr($directory,-1) == '/')
                    $directory = substr($directory,0,-1);

                    if(!file_exists($directory) || !is_dir($directory)) {
                    return FALSE;
                    }
                    elseif(!is_readable($directory)) {
                    return FALSE;
                    }
                    else {
                    $handle = opendir($directory);
                    while (FALSE !== ($item = readdir($handle)))
                    {
                    if($item != '.' && $item != '..')
                    {
                    $path = $directory.'/'.$item;
                    if(is_dir($path))
                    recursive_remove_directory($path);
                    else
                    unlink($path);
                    }
                    }
                    closedir($handle);
                    if($empty == FALSE)
                    {
                    if(!rmdir($directory))
                    return FALSE;
                    }
                    return TRUE;
                    }
                    }
                    recursive_remove_directory("../extranet/files/'($ClientID)'");
                    }
                    //end Recursive_Remove trigger

                    Its this part of the recursive remove that's stopping it from working:-

                    recursive_remove_directory("../extranet/files/'($ClientID)'");

                    With 'ClientID' being the variable I'm trying to pass with no success. Say the ClientID was 42 then if the line was:-

                    recursive_remove_directory("../extranet/files/42");

                    Then it would remove that directory and all others below it with no problem. Any ideas how I can pass the ClientID fromj the recordset RsClients to the transaction for it to work?

                    Actually if this was to work then I guess I could remove the non-recursive delete folder transaction.

                    Thanks

                    Glenn
                    • 7. Re: Delete Folder with all Subfolders and files
                      Günter Schenk Level 4
                      Hi Glennboy,

                      I think the main issue with your Custom Trigger respectively this particular line:

                      recursive_remove_directory("../extranet/files/'($ClientID)'");

                      ...is, that the Trigger is a custom PHP function which probably requires the transaction value to be defined as GLOBAL in order to detect it.

                      BTW, if "ClientID" is also an URL variable your´re passing to this page, you won´t need to declare it GLOBAL, but could use it right away like this:

                      recursive_remove_directory("../extranet/files/".$_GET['clientID']."");

                      I´m also sure that your current...

                      "../extranet/files/'($ClientID)'"

                      ...path definition doesn´t know that "$ClientID" is supposed to be a dynamic value, because if you embed PHP variables in literal text, you´d better do it this way:

                      "../extranet/files/".$_GET['clientID'].""

                      Cheers,
                      Günter Schenk
                      Adobe Community Expert, Dreamweaver
                      • 8. Re: Delete Folder with all Subfolders and files
                        Level 1
                        Hi Günter

                        That's great, it worked well. I also deleted the now superseded remove folder trigger, leaving just the custom trigger to delete the folders.

                        Couple of further questions.

                        1. How would I declare an ID such as "ClientID" global? Does this differ if like as in my case I'm passing ClientID as a URL variable?

                        2. I will have further specific folders that I will want to trigger individually below the folder 'ClientID', so if for example the next folder below was assigned by ProjectID would my recursive remove transaction look something like:-

                        recursive_remove_directory("../extranet/files/".$_GET['ClientID']."/".$_GET['ProjectID']." ");

                        Also what if the ProjectID was not a URL variable and direct from the Recordset.

                        Thanks for this.

                        Glennyboy
                        • 9. Re: Delete Folder with all Subfolders and files
                          Günter Schenk Level 4
                          Hi Glennboy,

                          --------
                          1. How would I declare an ID such as "ClientID" global?
                          --------

                          Let´s assume that "ClientID" is a transaction value and not an URL variable -- in order to have a function detect a transaction value which exists outside the function scope, please try (untested !) making it a GLOBAL variable like this:

                          function whatever {
                          GLOBAL $tNG->getColumnValue("ClientID");
                          $ClientID = $tNG->getColumnValue("ClientID");
                          ...
                          ...
                          ...
                          recursive_remove_directory("../extranet/files/".$ClientID."");
                          ...
                          ...
                          ...
                          }

                          The same should be possible with using recordset values like $row_queryname['ClientID'], but I´m not sure about that.

                          -------
                          Does this differ if like as in my case I'm passing ClientID as a URL variable?
                          --------

                          PHP treats $_GET, $_POST, $_COOKIE and $_SESSION variables as "super global" ones which - although they also exist outside the function scope - are instantly available within functions and don´t need to be "introduced" by declaring them "GLOBAL".

                          Cheers,
                          Günter Schenk
                          Adobe Community Expert, Dreamweaver
                          • 10. Re: Delete Folder with all Subfolders and files
                            Level 1
                            Günter

                            Great info.

                            Can I confirm that with 'function whatever' the 'whatever' is the name that you are giving the function, or is it simply part of the Global function?

                            Also was I correct in the case 2. above whereby you are passing x2 URL variables?

                            Cheers

                            Glennyboy
                            • 11. Re: Delete Folder with all Subfolders and files
                              Günter Schenk Level 4
                              Hi Glennboy

                              --------
                              Can I confirm that with 'function whatever' the 'whatever' is the name that you are giving the function
                              --------

                              "whatever" is just a placeholder for the name of any PHP function, and ADDT´s Custom Triggers are functions as well

                              -------
                              or is it simply part of the Global function?
                              -------

                              GLOBAL is not a function, it´s just a method to "import" outside variables into functions. Some brilliant info on what GLOBAL is and does is available here: http://de2.php.net/global

                              ------
                              Also was I correct in the case 2. above whereby you are passing x2 URL variables?
                              ------

                              as you succeeded integrating one URL variable into your dynamic path definition, using two or more URL variables should work the same.

                              The syntax of...

                              recursive_remove_directory("../extranet/files/".$_GET['ClientID']."/".$_GET['ProjectID']." ");

                              ...is just perfect BTW :-)

                              Cheers,
                              Günter Schenk
                              Adobe Community Expert, Dreamweaver
                              • 12. Re: Delete Folder with all Subfolders and files
                                Level 1
                                Hi Günter

                                Just to say thanks for your assistance. I may have more questions but that's great for now.

                                Best

                                Glennyboy