Source for file tree.php

Documentation is available at tree.php

  1. <?php
  2.  
  3. /**
  4.  * tree.php
  5.  *
  6.  * This file provides functions to walk trees of folders, for
  7.  * instance to delete a whole tree.
  8.  *
  9.  * @copyright 1999-2020 The SquirrelMail Project Team
  10.  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  11.  * @version $Id: tree.php 14845 2020-01-07 08:09:34Z pdontthink $
  12.  * @package squirrelmail
  13.  */
  14.  
  15. require_once(SM_PATH . 'functions/imap.php');
  16.  
  17. /**
  18.  * Recursive function to find the correct parent for a new node.
  19.  *
  20.  * @param mixed value the value to find a parent for
  21.  * @param int treeIndexToStart where to start the search, usually the root node (0)
  22.  * @param array tree the tree to search
  23.  * @return int the index of the parent
  24.  */
  25. function findParentForChild($value, $treeIndexToStart, $tree) {
  26.     // is $value in $tree[$treeIndexToStart]['value']
  27.     if ((isset($tree[$treeIndexToStart])) && (strstr($value, $tree[$treeIndexToStart]['value']))) {
  28.         // do I have children, if not then must be a childnode of the current node
  29.         if ($tree[$treeIndexToStart]['doIHaveChildren']) {
  30.             // loop through each subNode checking to see if we are a subNode of one of them
  31.             for ($i=0;$i< count($tree[$treeIndexToStart]['subNodes']);$i++) {
  32.             $result = findParentForChild($value, $tree[$treeIndexToStart]['subNodes'][$i], $tree);
  33.             if ($result > -1)
  34.                 return $result;
  35.             }
  36.             // if we aren't a child of one of the subNodes, must be a child of current node
  37.             return $treeIndexToStart;
  38.         } else
  39.             return $treeIndexToStart;
  40.     } else {
  41.         // we aren't a child of this node at all
  42.         return -1;
  43.     }
  44. }
  45.  
  46. /**
  47.  * Will insert a new value into the tree, based on a given comparison value.
  48.  *
  49.  * @param mixed comparisonValue the value to determine where the new element should be placed.
  50.  * @param mixed value the new node to insert
  51.  * @param array tree the tree to insert the node in, by ref
  52.  */
  53. function addChildNodeToTree($comparisonValue, $value, &$tree) {
  54.     $parentNode = findParentForChild($comparisonValue, 0, $tree);
  55.  
  56.     // create a new subNode
  57.     $newNodeIndex = count($tree);
  58.     $tree[$newNodeIndex]['value'] = $value;
  59.     $tree[$newNodeIndex]['doIHaveChildren'] = false;
  60.  
  61.     if ($tree[$parentNode]['doIHaveChildren'] == false) {
  62.         // make sure the parent knows it has children
  63.         $tree[$parentNode]['subNodes'][0] = $newNodeIndex;
  64.         $tree[$parentNode]['doIHaveChildren'] = true;
  65.     } else {
  66.         $nextSubNode = count($tree[$parentNode]['subNodes']);
  67.         // make sure the parent knows it has children
  68.         $tree[$parentNode]['subNodes'][$nextSubNode] = $newNodeIndex;
  69.     }
  70. }
  71.  
  72. /**
  73.  * Recursively walk the tree of trash mailboxes and delete all folders and messages
  74.  *
  75.  * @param int index the place in the tree to start, usually 0
  76.  * @param stream imap_stream the IMAP connection to send commands to
  77.  * @param array tree the tree to walk
  78.  * @return void 
  79.  */
  80. function walkTreeInPreOrderEmptyTrash($index, $imap_stream, $tree) {
  81.     global $trash_folder;
  82.     walkTreeInPreOrderEmptyFolder($index, $imap_stream, $tree, $trash_folder);
  83. }
  84.  
  85. /**
  86.  * Recursively walk the tree of mailboxes in the given folder and delete all folders and messages
  87.  *
  88.  * @param int index the place in the tree to start, usually 0
  89.  * @param stream imap_stream the IMAP connection to send commands to
  90.  * @param array tree the tree to walk
  91.  * @param mailbox the name of the root folder to empty
  92.  * @return void 
  93.  */
  94. function walkTreeInPreOrderEmptyFolder($index, $imap_stream, $tree, $mailbox) {
  95.     if ($tree[$index]['doIHaveChildren']) {
  96.         for ($j = 0; $j < count($tree[$index]['subNodes']); $j++) {
  97.             walkTreeInPreOrderEmptyTrash($tree[$index]['subNodes'][$j], $imap_stream, $tree);
  98.         }
  99.         if ($tree[$index]['value'] != $mailbox) {
  100.             sqimap_mailbox_delete($imap_stream, $tree[$index]['value']);
  101.         } else {
  102.             $mbx_response = sqimap_mailbox_select($imap_stream, $mailbox);
  103.             if ($mbx_response['EXISTS'] > 0) {
  104.                 sqimap_toggle_flag($imap_stream, '1:*', '\\Deleted', true, true);
  105.                // CLOSE === EXPUNGE and UNSELECT
  106.                sqimap_run_command($imap_stream,'CLOSE',false,$response,$message);
  107.             }
  108.         }
  109.     } else {
  110.         if ($tree[$index]['value'] != $mailbox) {
  111.             sqimap_mailbox_delete($imap_stream, $tree[$index]['value']);
  112.         } else {
  113.             $mbx_response = sqimap_mailbox_select($imap_stream, $mailbox);
  114.             if ($mbx_response['EXISTS'] > 0) {
  115.                 sqimap_toggle_flag($imap_stream, '1:*', '\\Deleted', true, true);
  116.                 // CLOSE === EXPUNGE and UNSELECT
  117.                 sqimap_run_command($imap_stream,'CLOSE',false,$response,$message);
  118.             }
  119.         }
  120.     }
  121. }
  122.  
  123.  
  124. /**
  125.  * Recursively delete a tree of mail folders.
  126.  *
  127.  * @param int index the place in the tree to start, usually 0
  128.  * @param stream imap_stream the IMAP connection to send commands to
  129.  * @param array tree the tree to walk
  130.  * @return void 
  131.  */
  132. function walkTreeInPreOrderDeleteFolders($index, $imap_stream, $tree) {
  133.     if ($tree[$index]['doIHaveChildren']) {
  134.         for ($j = 0; $j < count($tree[$index]['subNodes']); $j++) {
  135.             walkTreeInPreOrderDeleteFolders($tree[$index]['subNodes'][$j], $imap_stream, $tree);
  136.         }
  137.         sqimap_mailbox_delete($imap_stream, $tree[$index]['value']);
  138.     } else {
  139.         sqimap_mailbox_delete($imap_stream, $tree[$index]['value']);
  140.     }
  141. }
  142.  
  143. /**
  144.  * Recursively walk a tree of folders to create them under the trash folder.
  145.  */
  146. function walkTreeInPostOrderCreatingFoldersUnderTrash($index, $imap_stream, $tree, $topFolderName) {
  147.     global $trash_folder, $delimiter;
  148.  
  149.     $position = strrpos($topFolderName, $delimiter);
  150.     if ($position !== FALSE) {
  151.         $position++;
  152.     }
  153.     $subFolderName = substr($tree[$index]['value'], $position);
  154.  
  155.     if ($tree[$index]['doIHaveChildren']) {
  156.         // create new trash subfolder only if it does not exist.
  157.         if (!sqimap_mailbox_exists($imap_stream, $trash_folder . $delimiter . $subFolderName))
  158.             sqimap_mailbox_create($imap_stream, $trash_folder . $delimiter . $subFolderName, "");
  159.  
  160.         $mbx_response = sqimap_mailbox_select($imap_stream, $tree[$index]['value']);
  161.         $messageCount = $mbx_response['EXISTS'];
  162.         if ($messageCount > 0) {
  163.             sqimap_msgs_list_copy($imap_stream, '1:*', $trash_folder . $delimiter . $subFolderName);
  164.         }
  165.         // after copy close the mailbox to get in unselected state
  166.         sqimap_run_command($imap_stream,'CLOSE',false,$response,$message);
  167.         for ($j = 0;$j < count($tree[$index]['subNodes']); $j++)
  168.             walkTreeInPostOrderCreatingFoldersUnderTrash($tree[$index]['subNodes'][$j], $imap_stream, $tree, $topFolderName);
  169.     } else {
  170.         if (!sqimap_mailbox_exists($imap_stream, $trash_folder . $delimiter . $subFolderName))
  171.             sqimap_mailbox_create($imap_stream, $trash_folder . $delimiter . $subFolderName, '');
  172.         $mbx_response = sqimap_mailbox_select($imap_stream, $tree[$index]['value']);
  173.         $messageCount = $mbx_response['EXISTS'];
  174.         if ($messageCount > 0) {
  175.             sqimap_msgs_list_copy($imap_stream, '1:*', $trash_folder . $delimiter . $subFolderName);
  176.         }
  177.         // after copy close the mailbox to get in unselected state
  178.         sqimap_run_command($imap_stream,'CLOSE',false,$response,$message);
  179.     }
  180. }
  181.  
  182. /**
  183.  * Recursive function that outputs a tree In-Pre-Order.
  184.  * @param int index the node to start (usually 0)
  185.  * @param array tree the tree to walk
  186.  * @return void 
  187.  */
  188. function simpleWalkTreePre($index, $tree) {
  189.     if ($tree[$index]['doIHaveChildren']) {
  190.         for ($j = 0; $j < count($tree[$index]['subNodes']); $j++) {
  191.             simpleWalkTreePre($tree[$index]['subNodes'][$j], $tree);
  192.         }
  193.         echo $tree[$index]['value'] . '<br />';
  194.     } else {
  195.         echo $tree[$index]['value'] . '<br />';
  196.     }
  197. }

Documentation generated on Mon, 13 Jan 2020 04:23:43 +0100 by phpDocumentor 1.4.3