Merge remote-tracking branch 'upstream/4.4' into 4.4-4.5-2014-09-29-13-10-47
[civicrm-core.git] / CRM / Core / QuickForm / Action / Upload.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.5 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2014 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
26 */
27
28 /**
29 * Redefine the upload action.
30 *
31 * @package CRM
32 * @copyright CiviCRM LLC (c) 2004-2014
33 * $Id$
34 *
35 */
36 class CRM_Core_QuickForm_Action_Upload extends CRM_Core_QuickForm_Action {
37
38 /**
39 * the array of uploaded file names
40 * @var array
41 */
42 protected $_uploadNames;
43
44 /**
45 * The directory to store the uploaded files
46 * @var string
47 */
48 protected $_uploadDir;
49
50 /**
51 * class constructor
52 *
53 * @param object $stateMachine reference to state machine object
54 * @param string $uploadDir directory to store the uploaded files
55 * @param array $uploadNames element names of the various uploadable files
56 *
57 * @return \CRM_Core_QuickForm_Action_Upload
58 @access public
59 */
60 function __construct(&$stateMachine, $uploadDir, $uploadNames) {
61 parent::__construct($stateMachine);
62
63 $this->_uploadDir = $uploadDir;
64 $this->_uploadNames = $uploadNames;
65 }
66
67 /**
68 * upload and move the file if valid to the uploaded directory
69 *
70 * @param object $page the CRM_Core_Form object
71 * @param object $data the QFC data container
72 * @param string $pageName the name of the page which index the data container with
73 * @param string $uploadName the name of the uploaded file
74 *
75 * @return void
76 * @access private
77 */
78 function upload(&$page, &$data, $pageName, $uploadName) {
79 // make sure uploadName exists in the QF array
80 // else we skip, CRM-3427
81 if (empty($uploadName) ||
82 !isset($page->_elementIndex[$uploadName])
83 ) {
84 return;
85 }
86
87 // get the element containing the upload
88 $element = &$page->getElement($uploadName);
89 if ('file' == $element->getType()) {
90 if ($element->isUploadedFile()) {
91 // rename the uploaded file with a unique number at the end
92 $value = $element->getValue();
93
94 $newName = CRM_Utils_File::makeFileName($value['name']);
95 $status = $element->moveUploadedFile($this->_uploadDir, $newName);
96 if (!$status) {
97 CRM_Core_Error::statusBounce(ts('We could not move the uploaded file %1 to the upload directory %2. Please verify that the \'Temporary Files\' setting points to a valid path which is writable by your web server.', array(1 => $value['name'], 2 => $this->_uploadDir)));
98 }
99 if (!empty($data['values'][$pageName][$uploadName]['name'])) {
100 @unlink($this->_uploadDir . $data['values'][$pageName][$uploadName]);
101 }
102
103 $data['values'][$pageName][$uploadName] = array(
104 'name' => $this->_uploadDir . $newName,
105 'type' => $value['type'],
106 );
107 }
108 }
109 }
110
111 /**
112 * Processes the request.
113 *
114 * @param object $page CRM_Core_Form the current form-page
115 * @param string $actionName Current action name, as one Action object can serve multiple actions
116 *
117 * @return void
118 * @access public
119 */
120 function perform(&$page, $actionName) {
121 // like in Action_Next
122 $page->isFormBuilt() or $page->buildForm();
123
124 // so this is a brain-seizure moment, so hang tight (real tight!)
125 // the above buildForm potentially changes the action function with different args
126 // so basically the rug might have been pulled from us, so we actually just check
127 // and potentially call the right one
128 // this allows standalong form uploads to work nicely
129 $page->controller->_actions['upload']->realPerform($page, $actionName);
130 }
131
132 /**
133 * @param CRM_Core_Form $page
134 * @param $actionName
135 *
136 * @return mixed
137 */
138 function realPerform(&$page, $actionName) {
139 $pageName = $page->getAttribute('name');
140 $data = &$page->controller->container();
141 $data['values'][$pageName] = $page->exportValues();
142 $data['valid'][$pageName] = $page->validate();
143
144 if (!$data['valid'][$pageName]) {
145 return $page->handle('display');
146 }
147
148 foreach ($this->_uploadNames as $name) {
149 $this->upload($page, $data, $pageName, $name);
150 }
151
152 $state = &$this->_stateMachine->getState($pageName);
153 if (empty($state)) {
154 return $page->handle('display');
155 }
156
157 // the page is valid, process it before we jump to the next state
158 $page->mainProcess();
159
160 // check if destination is set, if so goto destination
161 $destination = $this->_stateMachine->getDestination();
162 if ($destination) {
163 $destination = urldecode($destination);
164 CRM_Utils_System::redirect($destination);
165 }
166 else {
167 return $state->handleNextState($page);
168 }
169 }
170 }
171