Merge branch '2013.10' into 2014.11
authorPhilipp Schüle <p.schuele@metaways.de>
Thu, 22 Oct 2015 09:39:07 +0000 (11:39 +0200)
committerPhilipp Schüle <p.schuele@metaways.de>
Thu, 22 Oct 2015 09:39:07 +0000 (11:39 +0200)
1  2 
tests/tine20/Filemanager/Frontend/JsonTests.php
tine20/Filemanager/Controller/Node.php

@@@ -614,7 -614,6 +614,7 @@@ class Filemanager_Frontend_JsonTests ex
              $target, 
              FALSE
          );
 +        
          $this->_objects['paths'][] = Filemanager_Controller_Node::getInstance()->addBasePath($target . '/testcontainer');
          $this->assertEquals(1, count($result));
          $this->_objects['containerids'][] = $result[0]['name']['id'];
      {
          $filesToCopy = $this->testCreateFileNodes();
          $file1 = $filesToCopy[0];
 +        $file2 = $filesToCopy[1];
          
          $this->setExpectedException('Filemanager_Exception_NodeExists');
 -        $result = $this->_json->copyNodes(array($file1), array($file1), FALSE);
 +        $result = $this->_json->copyNodes(array($file1), array($file2), FALSE);
      }
      
      /**
      {
          $filesToCopy = $this->testCreateFileNodes();
          $file1 = $filesToCopy[0];
 +        $file2 = $filesToCopy[1];
          
          try {
 -            $result = $this->_json->copyNodes(array($file1), array($file1), FALSE);
 +            $result = $this->_json->copyNodes(array($file1), array($file2), FALSE);
          } catch (Filemanager_Exception_NodeExists $fene) {
              $info = $fene->toArray();
              $this->assertEquals(1, count($info['existingnodesinfo']));
          $result = $this->_json->searchNodes($filter, array());
          
          $this->assertEquals(2, $result['totalcount']);
+         $initialNode = $result['results'][0];
          
-         $node = $this->_json->getNode($result['results'][0]['id']);
+         $node = $this->_json->getNode($initialNode['id']);
          $this->assertEquals('file', $node['type']);
          
          $node['description'] = 'UNITTEST';
          $node = $this->_json->saveNode($node);
          
          $this->assertEquals('UNITTEST', $node['description']);
+         $this->assertEquals($initialNode['contenttype'], $node['contenttype'], 'contenttype  not preserved');
          
          return $node;
      }
      }
      
      /**
 +     * test renaming a folder in a folder containing a folder with the same name
 +     *
 +     * @see: https://forge.tine20.org/mantisbt/view.php?id=10132
 +     */
 +     public function testRenameFolderInFolderContainingFolderAlready()
 +     {
 +        $path = '/personal/' .Tinebase_Core::getUser()->accountLoginName . '/' . $this->_getPersonalFilemanagerContainer()->name;
 +     
 +        $this->_json->createNode($path . '/Test1', 'folder', NULL, FALSE);
 +        $this->_json->createNode($path . '/Test1/Test2', 'folder', NULL, FALSE);
 +        $this->_json->createNode($path . '/Test1/Test3', 'folder', NULL, FALSE);
 +        
 +        $this->setExpectedException('Filemanager_Exception_NodeExists');
 +        
 +        $this->_json->moveNodes(array($path . '/Test1/Test3'), array($path . '/Test1/Test2'), FALSE);
 +     }
 +    
 +    /**
       * tests the recursive filter
       */
      public function testSearchRecursiveFilter()
      }
      
      /**
 +     * test preventing to copy a folder in its subfolder
 +     * 
 +     * @see: https://forge.tine20.org/mantisbt/view.php?id=9990
 +     */
 +    public function testMoveFolderIntoChildFolder()
 +    {
 +        $this->_json->createNode('/shared/Parent', 'folder', NULL, FALSE);
 +        $this->_json->createNode('/shared/Parent/Child', 'folder', NULL, FALSE);
 +        
 +        $this->setExpectedException('Filemanager_Exception_DestinationIsOwnChild');
 +        
 +        // this must not work
 +        $this->_json->moveNodes(array('/shared/Parent'), array('/shared/Parent/Child/Parent'), FALSE);
 +    }
 +    
 +    /**
 +     * test exception on moving to the same position
 +     * 
 +     * @see: https://forge.tine20.org/mantisbt/view.php?id=9990
 +     */
 +    public function testMoveFolderToSamePosition()
 +    {
 +        $this->_json->createNode('/shared/Parent', 'folder', NULL, FALSE);
 +        $this->_json->createNode('/shared/Parent/Child', 'folder', NULL, FALSE);
 +    
 +        $this->setExpectedException('Filemanager_Exception_DestinationIsSameNode');
 +    
 +        // this must not work
 +        $this->_json->moveNodes(array('/shared/Parent/Child'), array('/shared/Parent/Child'), FALSE);
 +    }
 +
 +    /**
 +     * test to move a folder containing another folder
 +     *
 +     * @see: https://forge.tine20.org/mantisbt/view.php?id=9990
 +     */
 +    public function testMove2FoldersOnToplevel()
 +    {
 +        $path = '/personal/' .Tinebase_Core::getUser()->accountLoginName . '/' . $this->_getPersonalFilemanagerContainer()->name;
 +    
 +        $this->_json->createNode($path . '/Parent', 'folder', NULL, FALSE);
 +        $this->_json->createNode($path . '/Parent/Child', 'folder', NULL, FALSE);
 +        $this->_json->createNode('/shared/Another', 'folder', NULL, FALSE);
 +    
 +        // move forth and back, no exception should occur
 +        $this->_json->moveNodes(array($path . '/Parent'), array('/shared/Parent'), FALSE);
 +        $this->_json->moveNodes(array('/shared/Parent'), array($path . '/Parent'), FALSE);
 +    
 +        try {
 +            $c = Tinebase_Container::getInstance()->getContainerByName('Filemanager', 'Parent', Tinebase_Model_Container::TYPE_SHARED);
 +            $this->fail('Container doesn\'t get deleted');
 +        } catch (Tinebase_Exception_NotFound $e) {
 +        }
 +        
 +        // may be any exception
 +        $e = new Tinebase_Exception('Dog eats cat');
 +    
 +        try {
 +            $this->_json->moveNodes(array($path . '/Parent'), array('/shared/Parent'), FALSE);
 +        } catch (Filemanager_Exception_NodeExists $e) {
 +        }
 +    
 +        // if $e gets overridden, an error occured (the exception Filemanager_Exception_NodeExists must not be thrown)
 +        $this->assertEquals('Tinebase_Exception', get_class($e));
 +    }
 +    
 +    /**
 +     * test creating a folder in a folder with the same name (below personal folders)
 +     *
 +     * @see: https://forge.tine20.org/mantisbt/view.php?id=10132
 +     */
 +    public function testCreateFolderInFolderWithSameName()
 +    {
 +        $path = '/personal/' .Tinebase_Core::getUser()->accountLoginName . '/' . $this->_getPersonalFilemanagerContainer()->name;
 +        
 +        $this->_json->createNode($path . '/Test1', 'folder', NULL, FALSE);
 +        $this->_json->createNode($path . '/Test1/Test1', 'folder', NULL, FALSE);
 +        $e = new Tinebase_Exception('nothing');
 +        try {
 +            $this->_json->createNode($path . '/Test1/Test1/Test2', 'folder', NULL, FALSE);
 +        } catch(Exception $e) {
 +            $this->fail('The folder couldn\'t be found, so it hasn\'t ben created');
 +        }
 +        
 +        $this->assertEquals('nothing', $e->getMessage());
 +    }
 +    
 +    /**
       * get other users container
       * 
       * @return Tinebase_Model_Container
      protected function _getOtherUserContainer()
      {
          if (!$this->_otherUserContainer) {
 -            $sclever = array_value('sclever', Zend_Registry::get('personas'));
 +            $sclever = Tinebase_Helper::array_value('sclever', Zend_Registry::get('personas'));
              
              $this->_otherUserContainer = Tinebase_Container::getInstance()->getDefaultContainer('Filemanager', $sclever->getId());
              Tinebase_Container::getInstance()->addGrants(
@@@ -112,9 -112,10 +112,10 @@@ class Filemanager_Controller_Node exten
       */
      protected function _inspectBeforeUpdate($_record, $_oldRecord)
      {
+         // protect against file object spoofing
          foreach (array_keys($_record->toArray()) as $property) {
-             if (! in_array($property, array('id', 'name', 'description', 'relations', 'customfields', 'tags', 'notes', 'object_id'))) {
-                 unset($_record->{$property});
+             if (! in_array($property, array('name', 'description', 'relations', 'customfields', 'tags', 'notes'))) {
+                 $_record->{$property} = $_oldRecord->{$property};
              }
          }
      }
  
              try {
                  $node = $this->_createNode($filename, $_type, $tempFileId, $_forceOverwrite);
 -                $result->addRecord($node);
 +                if ($node) {
 +                    $result->addRecord($node);
 +                }
              } catch (Filemanager_Exception_NodeExists $fene) {
                  $nodeExistsException = $this->_handleNodeExistsException($fene, $nodeExistsException);
              }
          }
          
          $newNode = $this->_createNodeInBackend($newNodePath, $_type, $_tempFileId);
 +        
          $this->resolveContainerAndAddPath($newNode, $parentPathRecord, $container);
          return $newNode;
      }
          if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . 
              ' Creating new path ' . $_statpath . ' of type ' . $_type);
          
 +        $node = NULL;
          switch ($_type) {
              case Tinebase_Model_Tree_Node::TYPE_FILE:
 -                $this->_backend->copyTempfile($_tempFileId, $_statpath);
 +                 $this->_backend->copyTempfile($_tempFileId, $_statpath);
                  break;
              case Tinebase_Model_Tree_Node::TYPE_FOLDER:
 -                $this->_backend->mkdir($_statpath);
 +                $node = $this->_backend->mkdir($_statpath);
                  break;
          }
          
 -        return $this->_backend->stat($_statpath);
 +        return $node ? $node : $this->_backend->stat($_statpath);
      }
      
      /**
      {
          if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__
              . ' Check existance of ' . $_path->statpath);
 -        
 +
          if ($this->_backend->fileExists($_path->statpath)) {
 -            $existsException = new Filemanager_Exception_NodeExists();
 -            $existsException->addExistingNodeInfo(($_node !== NULL) ? $_node : $this->_backend->stat($_path->statpath));
 -            throw $existsException;
 +            
 +            if (! $_node) {
 +                $_node = $this->_backend->stat($_path->statpath);
 +            }
 +            
 +            if ($_node) {
 +                $existsException = new Filemanager_Exception_NodeExists();
 +                $existsException->addExistingNodeInfo($_node);
 +                throw $existsException;
 +            }
          }
      }
          
          
          $app = Tinebase_Application::getInstance()->getApplicationByName($this->_applicationName);
          $flatpathWithoutBasepath = Tinebase_Model_Tree_Node_Path::removeAppIdFromPath($_path->flatpath, $app);
 -        
 -        foreach ($records as $record) {
 -            $record->path = $flatpathWithoutBasepath . '/' . $record->name;
 -            
 -            $aclContainer = NULL;
 -            if (! $_path->container) {
 -                // resolve container
 -                if (! $record->name instanceof Tinebase_Model_Container) {
 -                    $idx = $containers->getIndexById($record->name);
 -                    if ($idx !== FALSE) {
 -                        $aclContainer = $containers[$idx];
 -                        $record->name = $aclContainer;
 -                        $record->path = $flatpathWithoutBasepath . '/' . $record->name->name;
 +        if ($records) {
 +            foreach ($records as $record) {
 +                $record->path = $flatpathWithoutBasepath . '/' . $record->name;
 +                
 +                $aclContainer = NULL;
 +                if (! $_path->container) {
 +                    // resolve container
 +                    if (! $record->name instanceof Tinebase_Model_Container) {
 +                        $idx = $containers->getIndexById($record->name);
 +                        if ($idx !== FALSE) {
 +                            $aclContainer = $containers[$idx];
 +                            $record->name = $aclContainer;
 +                            $record->path = $flatpathWithoutBasepath . '/' . $record->name->name;
 +                        }
                      }
 +                } else {
 +                    $aclContainer = $_path->container;
                  }
 -            } else {
 -                $aclContainer = $_path->container;
 -            }
 -            
 -            if ($aclContainer) {
 -                $record->account_grants = Tinebase_Container::getInstance()->getGrantsOfAccount(
 -                    Tinebase_Core::getUser(), 
 -                    $aclContainer
 -                )->toArray();
 -                $aclContainer->account_grants = $record->account_grants;
                  
 -                // needed for sorting
 -                $record->container_name = $aclContainer->name;
 +                if ($aclContainer) {
 +                    $record->account_grants = Tinebase_Container::getInstance()->getGrantsOfAccount(
 +                        Tinebase_Core::getUser(), 
 +                        $aclContainer
 +                    )->toArray();
 +                    $aclContainer->account_grants = $record->account_grants;
 +                    
 +                    // needed for sorting
 +                    $record->container_name = $aclContainer->name;
 +                }
              }
          }
      }
          foreach ($_sourceFilenames as $idx => $source) {
              $sourcePathRecord = Tinebase_Model_Tree_Node_Path::createFromPath($this->addBasePath($source));
              $destinationPathRecord = $this->_getDestinationPath($_destinationFilenames, $idx, $sourcePathRecord);
 -
 +            
 +            if ($this->_backend->fileExists($destinationPathRecord->statpath) && $sourcePathRecord->flatpath == $destinationPathRecord->flatpath) {
 +                throw new Filemanager_Exception_DestinationIsSameNode();
 +            }
 +            
 +            // test if destination is subfolder of source
 +            $dest = explode('/', $destinationPathRecord->statpath);
 +            $source = explode('/', $sourcePathRecord->statpath);
 +            $isSub = TRUE;
 +            
 +            for ($i = 0; $i < count($source); $i++) {
 +                
 +                if (! isset($dest[$i])) {
 +                    break;
 +                }
 +                
 +                if ($source[$i] != $dest[$i]) {
 +                    $isSub = FALSE;
 +                }
 +            }
 +            if ($isSub) {
 +                throw new Filemanager_Exception_DestinationIsOwnChild();
 +            }
 +            
              try {
                  if ($_action === 'move') {
                      $node = $this->_moveNode($sourcePathRecord, $destinationPathRecord, $_forceOverwrite);
              $destinationNodeName = $destination->container->getId();
          } else {
              $this->_checkPathACL($destinationParentPathRecord, 'update');
 -            
              if ($source->getParent()->flatpath != $destinationParentPathRecord->flatpath) {
                  try {
                      $this->_checkIfExists($destination);
                          throw $fene;
                      }
                  }
 +            } else {
 +                if (! $_forceOverwrite) {
 +                    $this->_checkIfExists($destination);
 +                }
              }
          }
          
 +        // remove source container if it doesn't have the same parent - otherwise a new one will be created
 +        if ($source->isToplevelPath() && $source->getParent()->getId() !== $destination->getParent()->getId()) {
 +            Tinebase_Container::getInstance()->deleteContainer($source->container->getId());
 +        }
 +        
          if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__
              . ' Rename Folder ' . $source->statpath . ' -> ' . $destination->statpath);
          
                  . ' Moving container ' . $source->container->name . ' to ' . $destination->flatpath);
          
              $this->_checkACLContainer($source->container, 'update');
 -        
 +            
              $container = $source->container;
              if ($container->name !== $destination->name) {
                  try {