/** * Creates a downloadable file from the given table of the users database * @param string $table table in the users database * @param string $suffix * @return array $response */ private function _createDownloadFile($table, $format, $regen = false) { // sanity check for format if (!in_array($format, Daiquiri_Config::getInstance()->query->download->adapter->enabled->toArray())) { throw new Exception('Error: format not valid.'); } // create link and file sysytem path for table dump $username = Daiquiri_Auth::getInstance()->getCurrentUsername(); $suffix = Daiquiri_Config::getInstance()->query->download->adapter->config->{$format}->suffix; $filename = $this->_generateFileName($table, $suffix); $url = '/query/download/file?table=' . $table . '&format=' . $format; $dir = Daiquiri_Config::getInstance()->query->download->dir . DIRECTORY_SEPARATOR . $username; $file = $dir . DIRECTORY_SEPARATOR . $filename; // get queue type and validate $queueType = strtolower(Daiquiri_Config::getInstance()->query->download->type); if ($queueType !== "direct" and $queueType !== "gearman") { throw new Exception('Download queue type not valid'); } // create dir if neccessary if (!is_dir($dir)) { if (mkdir($dir) === false) { return array('status' => 'error', 'error' => 'Configuration of download directory wrong, please contact support.'); } chmod($dir, 0775); } // delete the old file if regen is set if ($regen === true) { if (file_exists($file . ".lock")) { throw new Daiquiri_Exception_Forbidden(); } // delete the files... if (file_exists($file)) { unlink($file); } if (file_exists($file . ".err")) { unlink($file . ".err"); } } if (!file_exists($file) && ($queueType === "direct" || empty($queueType))) { //get the user db name $username = Daiquiri_Auth::getInstance()->getCurrentUsername(); $db = Daiquiri_Config::getInstance()->getUserDbName($username); // get the resource and create dump $resource = new Data_Model_Resource_Viewer(); $resource->init($db, $table); try { $resource->dumpTable($format, $file); } catch (Exception $e) { return array('status' => 'error', 'error' => array('form' => $e->getMessage() . ' Please contact support.')); } } if ((!file_exists($file) || file_exists($file . ".lock")) && $queueType === "gearman") { // check if gearman is up and running exec('pgrep gearmand', $output, $return); if ($return != 0) { throw new Exception('gearmand is not running.'); } // check if $restartGeamanManager = false; $pidfile = Daiquiri_Config::getInstance()->query->download->gearman->pid; if (file_exists($pidfile)) { $pid = file_get_contents($pidfile); exec('ps -p ' . $pid, $output, $return); if ($return != 0) { $restartGeamanManager = true; } } else { $restartGeamanManager = true; } if ($restartGeamanManager) { // check if we have write access to actually create this PID file if (!is_writable(dirname(Daiquiri_Config::getInstance()->query->download->gearman->pid))) { return array('status' => 'error', 'error' => 'Cannot write to the gearman PID file, please contact support.'); } $gearmanConf = Daiquiri_Config::getInstance()->query->download->gearman; // not there, start GearmanManager $cmd = escapeshellcmd($gearmanConf->manager) . ' -d' . ' -D ' . escapeshellcmd($gearmanConf->numThread) . ' -h ' . escapeshellcmd($gearmanConf->host) . ':' . escapeshellcmd($gearmanConf->port) . ' -P ' . escapeshellcmd($gearmanConf->pid) . ' -w ' . escapeshellcmd($gearmanConf->workerDir) . ' -r 1 > /tmp/Daiquiri_GearmanManager.log &'; shell_exec($cmd); // DOES NOT WORK IN NEWER PHP, NEED TO BE FIXED // http://stackoverflow.com/questions/12322811/call-time-pass-by-reference-has-been-removed // check if pid exists, if not, an error occured - wait for 10 seconds to start gearman manager $count = 0; while (!file_exists($gearmanConf->pid)) { $count += 1; sleep(1); if ($count > 10) { throw new Exception('Error: Could not start GearmanManager.'); } } } // check if lockfile is present and if not, create if (!file_exists($file . ".lock")) { if (file_exists($file . ".err")) { return array('status' => 'error', 'error' => 'An error file exists on the server, please contact support.'); } // write lock file touch($file . ".lock"); // get the user db name $username = Daiquiri_Auth::getInstance()->getCurrentUsername(); $db = Daiquiri_Config::getInstance()->getUserDbName($username); // get the resource and create dump $resource = new Data_Model_Resource_Viewer(); $resource->init($db, $table); try { $resource->dumpTableGearman($format, $file); } catch (Exception $e) { unlink($file . ".lock"); return array('status' => 'error', 'error' => array('form' => $e->getMessage() . ' Please contact support.')); } return array('status' => 'pending', 'format' => $format); } else { return array('status' => 'pending', 'format' => $format); } } return array('status' => 'ok', 'link' => Daiquiri_Config::getInstance()->getSiteUrl() . $url, 'format' => $format); }