diff --git a/CHANGELOG b/CHANGELOG index 026d1f06a..96e34b570 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,10 @@ +-------------------------------------------------------------------------------- + Changes in version 5.0.10 +-------------------------------------------------------------------------------- +- merged changes from 4.3.33 +- new javascript base calendar +- overhaul indexing of documents + -------------------------------------------------------------------------------- Changes in version 5.0.9 -------------------------------------------------------------------------------- @@ -63,6 +70,16 @@ - add .xml to online file types by default - add home folder for users +-------------------------------------------------------------------------------- + Changes in version 4.3.33 +-------------------------------------------------------------------------------- +- add support for fine-uploader as a replacement for the old jumploader +- when importing from filesystem, the imported folder can be deleted afterwards +- new calendar +- move folder/document properly checks for access right if done by drag and + drop (Closes #309) +- show workflow log on document details page + -------------------------------------------------------------------------------- Changes in version 4.3.32 -------------------------------------------------------------------------------- diff --git a/Makefile b/Makefile index 39ac4c2b3..3cb42ba1e 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -VERSION=5.0.9 +VERSION=5.0.10 SRC=CHANGELOG inc conf utils index.php languages views op out controllers doc styles TODO LICENSE webdav install restapi pdfviewer # webapp diff --git a/SeedDMS_Core/Core/inc.ClassAttribute.php b/SeedDMS_Core/Core/inc.ClassAttribute.php index 9a8bad29d..d8842c1f8 100644 --- a/SeedDMS_Core/Core/inc.ClassAttribute.php +++ b/SeedDMS_Core/Core/inc.ClassAttribute.php @@ -207,21 +207,21 @@ class SeedDMS_Core_Attribute { /* {{{ */ switch(get_class($this->_obj)) { case $this->_dms->getClassname('document'): if(trim($value) === '') - $queryStr = "DELETE FROM tblDocumentAttributes WHERE `document` = " . $this->_obj->getID() . " AND `attrdef` = " . $this->_attrdef->getId(); + $queryStr = "DELETE FROM `tblDocumentAttributes` WHERE `document` = " . $this->_obj->getID() . " AND `attrdef` = " . $this->_attrdef->getId(); else - $queryStr = "UPDATE tblDocumentAttributes SET value = ".$db->qstr($value)." WHERE `document` = " . $this->_obj->getID() . " AND `attrdef` = " . $this->_attrdef->getId(); + $queryStr = "UPDATE `tblDocumentAttributes` SET `value` = ".$db->qstr($value)." WHERE `document` = " . $this->_obj->getID() . " AND `attrdef` = " . $this->_attrdef->getId(); break; case $this->_dms->getClassname('documentcontent'): if(trim($value) === '') - $queryStr = "DELETE FROM tblDocumentContentAttributes WHERE `content` = " . $this->_obj->getID() . " AND `attrdef` = " . $this->_attrdef->getId(); + $queryStr = "DELETE FROM `tblDocumentContentAttributes` WHERE `content` = " . $this->_obj->getID() . " AND `attrdef` = " . $this->_attrdef->getId(); else - $queryStr = "UPDATE tblDocumentContentAttributes SET value = ".$db->qstr($value)." WHERE `content` = " . $this->_obj->getID() . " AND `attrdef` = " . $this->_attrdef->getId(); + $queryStr = "UPDATE `tblDocumentContentAttributes` SET `value` = ".$db->qstr($value)." WHERE `content` = " . $this->_obj->getID() . " AND `attrdef` = " . $this->_attrdef->getId(); break; case $this->_dms->getClassname('folder'): if(trim($value) === '') - $queryStr = "DELETE FROM tblFolderAttributes WHERE `folder` = " . $this->_obj->getID() . " AND `attrdef` = " . $this->_attrdef->getId(); + $queryStr = "DELETE FROM `tblFolderAttributes WHERE` `folder` = " . $this->_obj->getID() . " AND `attrdef` = " . $this->_attrdef->getId(); else - $queryStr = "UPDATE tblFolderAttributes SET value = ".$db->qstr($value)." WHERE `folder` = " . $this->_obj->getID() . " AND `attrdef` = " . $this->_attrdef->getId(); + $queryStr = "UPDATE `tblFolderAttributes` SET `value` = ".$db->qstr($value)." WHERE `folder` = " . $this->_obj->getID() . " AND `attrdef` = " . $this->_attrdef->getId(); break; default: return false; @@ -446,7 +446,7 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */ function setName($name) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblAttributeDefinitions SET name =".$db->qstr($name)." WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblAttributeDefinitions` SET `name` =".$db->qstr($name)." WHERE `id` = " . $this->_id; $res = $db->getResult($queryStr); if (!$res) return false; @@ -476,7 +476,7 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */ function setObjType($objtype) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblAttributeDefinitions SET objtype =".intval($objtype)." WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblAttributeDefinitions` SET `objtype` =".intval($objtype)." WHERE `id` = " . $this->_id; $res = $db->getResult($queryStr); if (!$res) return false; @@ -506,7 +506,7 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */ function setType($type) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblAttributeDefinitions SET type =".intval($type)." WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblAttributeDefinitions` SET `type` =".intval($type)." WHERE `id` = " . $this->_id; $res = $db->getResult($queryStr); if (!$res) return false; @@ -531,7 +531,7 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */ function setMultipleValues($mv) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblAttributeDefinitions SET multiple =".intval($mv)." WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblAttributeDefinitions` SET `multiple` =".intval($mv)." WHERE `id` = " . $this->_id; $res = $db->getResult($queryStr); if (!$res) return false; @@ -553,7 +553,7 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */ function setMinValues($minvalues) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblAttributeDefinitions SET minvalues =".intval($minvalues)." WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblAttributeDefinitions` SET `minvalues` =".intval($minvalues)." WHERE `id` = " . $this->_id; $res = $db->getResult($queryStr); if (!$res) return false; @@ -575,7 +575,7 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */ function setMaxValues($maxvalues) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblAttributeDefinitions SET maxvalues =".intval($maxvalues)." WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblAttributeDefinitions` SET `maxvalues` =".intval($maxvalues)." WHERE `id` = " . $this->_id; $res = $db->getResult($queryStr); if (!$res) return false; @@ -671,7 +671,7 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblAttributeDefinitions SET valueset =".$db->qstr($valuesetstr)." WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblAttributeDefinitions` SET `valueset` =".$db->qstr($valuesetstr)." WHERE `id` = " . $this->_id; $res = $db->getResult($queryStr); if (!$res) return false; @@ -701,7 +701,7 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */ function setRegex($regex) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblAttributeDefinitions SET regex =".$db->qstr($regex)." WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblAttributeDefinitions` SET `regex` =".$db->qstr($regex)." WHERE `id` = " . $this->_id; $res = $db->getResult($queryStr); if (!$res) return false; @@ -721,13 +721,13 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */ function isUsed() { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "SELECT * FROM tblDocumentAttributes WHERE attrdef=".$this->_id; + $queryStr = "SELECT * FROM `tblDocumentAttributes` WHERE `attrdef`=".$this->_id; $resArr = $db->getResultArray($queryStr); if (is_array($resArr) && count($resArr) == 0) { - $queryStr = "SELECT * FROM tblFolderAttributes WHERE attrdef=".$this->_id; + $queryStr = "SELECT * FROM `tblFolderAttributes` WHERE `attrdef`=".$this->_id; $resArr = $db->getResultArray($queryStr); if (is_array($resArr) && count($resArr) == 0) { - $queryStr = "SELECT * FROM tblDocumentContentAttributes WHERE attrdef=".$this->_id; + $queryStr = "SELECT * FROM `tblDocumentContentAttributes` WHERE `attrdef`=".$this->_id; $resArr = $db->getResultArray($queryStr); if (is_array($resArr) && count($resArr) == 0) { @@ -780,7 +780,7 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */ $result = array('docs'=>array(), 'folders'=>array(), 'contents'=>array()); if($this->_objtype == SeedDMS_Core_AttributeDefinition::objtype_all || $this->_objtype == SeedDMS_Core_AttributeDefinition::objtype_document) { - $queryStr = "SELECT * FROM tblDocumentAttributes WHERE attrdef=".$this->_id; + $queryStr = "SELECT * FROM `tblDocumentAttributes` WHERE `attrdef`=".$this->_id; if($limit) $queryStr .= " limit ".(int) $limit; $resArr = $db->getResultArray($queryStr); @@ -791,7 +791,7 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */ } } } - $queryStr = "SELECT count(*) c, value FROM tblDocumentAttributes WHERE attrdef=".$this->_id." GROUP BY value ORDER BY c DESC"; + $queryStr = "SELECT count(*) c, `value` FROM `tblDocumentAttributes` WHERE `attrdef`=".$this->_id." GROUP BY `value` ORDER BY c DESC"; $resArr = $db->getResultArray($queryStr); if($resArr) { $result['frequencies']['document'] = $resArr; @@ -800,7 +800,7 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */ if($this->_objtype == SeedDMS_Core_AttributeDefinition::objtype_all || $this->_objtype == SeedDMS_Core_AttributeDefinition::objtype_folder) { - $queryStr = "SELECT * FROM tblFolderAttributes WHERE attrdef=".$this->_id; + $queryStr = "SELECT * FROM `tblFolderAttributes` WHERE `attrdef`=".$this->_id; if($limit) $queryStr .= " limit ".(int) $limit; $resArr = $db->getResultArray($queryStr); @@ -811,7 +811,7 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */ } } } - $queryStr = "SELECT count(*) c, value FROM tblFolderAttributes WHERE attrdef=".$this->_id." GROUP BY value ORDER BY c DESC"; + $queryStr = "SELECT count(*) c, `value` FROM `tblFolderAttributes` WHERE `attrdef`=".$this->_id." GROUP BY `value` ORDER BY c DESC"; $resArr = $db->getResultArray($queryStr); if($resArr) { $result['frequencies']['folder'] = $resArr; @@ -820,7 +820,7 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */ if($this->_objtype == SeedDMS_Core_AttributeDefinition::objtype_all || $this->_objtype == SeedDMS_Core_AttributeDefinition::objtype_documentcontent) { - $queryStr = "SELECT * FROM tblDocumentContentAttributes WHERE attrdef=".$this->_id; + $queryStr = "SELECT * FROM `tblDocumentContentAttributes` WHERE `attrdef`=".$this->_id; if($limit) $queryStr .= " limit ".(int) $limit; $resArr = $db->getResultArray($queryStr); @@ -831,7 +831,7 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */ } } } - $queryStr = "SELECT count(*) c, value FROM tblDocumentContentAttributes WHERE attrdef=".$this->_id." GROUP BY value ORDER BY c DESC"; + $queryStr = "SELECT count(*) c, `value` FROM `tblDocumentContentAttributes` WHERE `attrdef`=".$this->_id." GROUP BY `value` ORDER BY c DESC"; $resArr = $db->getResultArray($queryStr); if($resArr) { $result['frequencies']['content'] = $resArr; @@ -854,7 +854,7 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */ return false; // Delete user itself - $queryStr = "DELETE FROM tblAttributeDefinitions WHERE id = " . $this->_id; + $queryStr = "DELETE FROM `tblAttributeDefinitions` WHERE `id` = " . $this->_id; if (!$db->getResult($queryStr)) return false; return true; @@ -873,7 +873,7 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */ $result = array('docs'=>array(), 'folders'=>array(), 'contents'=>array()); if($this->_objtype == SeedDMS_Core_AttributeDefinition::objtype_all || $this->_objtype == SeedDMS_Core_AttributeDefinition::objtype_document) { - $queryStr = "SELECT * FROM tblDocumentAttributes WHERE attrdef=".$this->_id." AND value=".$db->qstr($attrvalue); + $queryStr = "SELECT * FROM `tblDocumentAttributes` WHERE `attrdef`=".$this->_id." AND `value`=".$db->qstr($attrvalue); if($limit) $queryStr .= " limit ".(int) $limit; $resArr = $db->getResultArray($queryStr); @@ -888,7 +888,7 @@ class SeedDMS_Core_AttributeDefinition { /* {{{ */ if($this->_objtype == SeedDMS_Core_AttributeDefinition::objtype_all || $this->_objtype == SeedDMS_Core_AttributeDefinition::objtype_folder) { - $queryStr = "SELECT * FROM tblFolderAttributes WHERE attrdef=".$this->_id." AND value=".$db->qstr($attrvalue); + $queryStr = "SELECT * FROM `tblFolderAttributes` WHERE `attrdef`=".$this->_id." AND `value`=".$db->qstr($attrvalue); if($limit) $queryStr .= " limit ".(int) $limit; $resArr = $db->getResultArray($queryStr); diff --git a/SeedDMS_Core/Core/inc.ClassDMS.php b/SeedDMS_Core/Core/inc.ClassDMS.php index 2f632e959..9c51be665 100644 --- a/SeedDMS_Core/Core/inc.ClassDMS.php +++ b/SeedDMS_Core/Core/inc.ClassDMS.php @@ -344,7 +344,7 @@ class SeedDMS_Core_DMS { $this->callbacks = array(); $this->version = '@package_version@'; if($this->version[0] == '@') - $this->version = '5.0.9'; + $this->version = '5.0.10'; } /* }}} */ /** @@ -411,7 +411,7 @@ class SeedDMS_Core_DMS { $tbllist = explode(',',strtolower(join(',',$tbllist))); if(!array_search('tblversion', $tbllist)) return false; - $queryStr = "SELECT * FROM tblVersion order by major,minor,subminor limit 1"; + $queryStr = "SELECT * FROM `tblVersion` order by `major`,`minor`,`subminor` limit 1"; $resArr = $this->db->getResultArray($queryStr); if (is_bool($resArr) && $resArr == false) return false; @@ -433,7 +433,7 @@ class SeedDMS_Core_DMS { $tbllist = explode(',',strtolower(join(',',$tbllist))); if(!array_search('tblversion', $tbllist)) return true; - $queryStr = "SELECT * FROM tblVersion order by major,minor,subminor limit 1"; + $queryStr = "SELECT * FROM `tblVersion` order by `major`,`minor`,`subminor` limit 1"; $resArr = $this->db->getResultArray($queryStr); if (is_bool($resArr) && $resArr == false) return false; @@ -601,7 +601,7 @@ class SeedDMS_Core_DMS { function getDocumentContent($id) { /* {{{ */ if (!is_numeric($id)) return false; - $queryStr = "SELECT * FROM tblDocumentContent WHERE id = ".(int) $id; + $queryStr = "SELECT * FROM `tblDocumentContent` WHERE `id` = ".(int) $id; $resArr = $this->db->getResultArray($queryStr); if (is_bool($resArr) && $resArr == false) return false; @@ -838,25 +838,9 @@ class SeedDMS_Core_DMS { $totalDocs = 0; if($mode & 0x1) { $searchKey = ""; - $searchFields = array(); - if (in_array(1, $searchin)) { - $searchFields[] = "`tblDocuments`.`keywords`"; - } - if (in_array(2, $searchin)) { - $searchFields[] = "`tblDocuments`.`name`"; - } - if (in_array(3, $searchin)) { - $searchFields[] = "`tblDocuments`.`comment`"; - $searchFields[] = "`tblDocumentContent`.`comment`"; - } - if (in_array(4, $searchin)) { - $searchFields[] = "`tblDocumentAttributes`.`value`"; - $searchFields[] = "`tblDocumentContentAttributes`.`value`"; - } - if (in_array(5, $searchin)) { - $searchFields[] = "`tblDocuments`.`id`"; - } + $classname = $this->classnames['document']; + $searchFields = $classname::getSearchFields($searchin); if (count($searchFields)>0) { foreach ($tkeys as $key) { @@ -1030,7 +1014,7 @@ class SeedDMS_Core_DMS { if($searchKey || $searchOwner || $searchCategories || $searchCreateDate || $searchExpirationDate || $searchAttributes || $status) { // Count the number of rows that the search will produce. - $resArr = $this->db->getResultArray("SELECT COUNT(*) AS num FROM (SELECT DISTINCT `tblDocuments`.id ".$searchQuery.") a"); + $resArr = $this->db->getResultArray("SELECT COUNT(*) AS num FROM (SELECT DISTINCT `tblDocuments`.`id` ".$searchQuery.") a"); $totalDocs = 0; if (is_numeric($resArr[0]["num"]) && $resArr[0]["num"]>0) { $totalDocs = (integer)$resArr[0]["num"]; @@ -1124,7 +1108,7 @@ class SeedDMS_Core_DMS { function getFolderByName($name, $folder=null) { /* {{{ */ if (!$name) return false; - $queryStr = "SELECT * FROM tblFolders WHERE name = " . $this->db->qstr($name); + $queryStr = "SELECT * FROM `tblFolders` WHERE `name` = " . $this->db->qstr($name); if($folder) $queryStr .= " AND `parent` = ". $folder->getID(); $queryStr .= " LIMIT 1"; @@ -1150,7 +1134,7 @@ class SeedDMS_Core_DMS { * @return array list of errors */ function checkFolders() { /* {{{ */ - $queryStr = "SELECT * FROM tblFolders"; + $queryStr = "SELECT * FROM `tblFolders`"; $resArr = $this->db->getResultArray($queryStr); if (is_bool($resArr) && $resArr === false) @@ -1184,7 +1168,7 @@ class SeedDMS_Core_DMS { * @return array list of errors */ function checkDocuments() { /* {{{ */ - $queryStr = "SELECT * FROM tblFolders"; + $queryStr = "SELECT * FROM `tblFolders`"; $resArr = $this->db->getResultArray($queryStr); if (is_bool($resArr) && $resArr === false) @@ -1195,7 +1179,7 @@ class SeedDMS_Core_DMS { $fcache[$rec['id']] = array('name'=>$rec['name'], 'parent'=>$rec['parent'], 'folderList'=>$rec['folderList']); } - $queryStr = "SELECT * FROM tblDocuments"; + $queryStr = "SELECT * FROM `tblDocuments`"; $resArr = $this->db->getResultArray($queryStr); if (is_bool($resArr) && $resArr === false) @@ -1295,9 +1279,11 @@ class SeedDMS_Core_DMS { } if($role == '') $role = '0'; - if(trim($pwdexpiration) == '') + if(trim($pwdexpiration) == '' || trim($pwdexpiration) == 'never') $pwdexpiration = '0000-00-00 00:00:00'; - $queryStr = "INSERT INTO tblUsers (login, pwd, fullName, email, language, theme, comment, role, hidden, disabled, pwdExpiration, quota, homefolder) VALUES (".$db->qstr($login).", ".$db->qstr($pwd).", ".$db->qstr($fullName).", ".$db->qstr($email).", '".$language."', '".$theme."', ".$db->qstr($comment).", '".intval($role)."', '".intval($isHidden)."', '".intval($isDisabled)."', ".$db->qstr($pwdexpiration).", '".intval($quota)."', ".($homefolder ? intval($homefolder) : "NULL").")"; + elseif(trim($pwdexpiration) == 'now') + $pwdexpiration = date('Y-m-d H:i:s'); + $queryStr = "INSERT INTO `tblUsers` (`login`, `pwd`, `fullName`, `email`, `language`, `theme`, `comment`, `role`, `hidden`, `disabled`, `pwdExpiration`, `quota`, `homefolder`) VALUES (".$db->qstr($login).", ".$db->qstr($pwd).", ".$db->qstr($fullName).", ".$db->qstr($email).", '".$language."', '".$theme."', ".$db->qstr($comment).", '".intval($role)."', '".intval($isHidden)."', '".intval($isDisabled)."', ".$db->qstr($pwdexpiration).", '".intval($quota)."', ".($homefolder ? intval($homefolder) : "NULL").")"; $res = $this->db->getResult($queryStr); if (!$res) return false; @@ -1360,7 +1346,7 @@ class SeedDMS_Core_DMS { return false; } - $queryStr = "INSERT INTO tblGroups (name, comment) VALUES (".$this->db->qstr($name).", ".$this->db->qstr($comment).")"; + $queryStr = "INSERT INTO `tblGroups` (`name`, `comment`) VALUES (".$this->db->qstr($name).", ".$this->db->qstr($comment).")"; if (!$this->db->getResult($queryStr)) return false; @@ -1381,7 +1367,7 @@ class SeedDMS_Core_DMS { if (!is_numeric($id)) return false; - $queryStr = "SELECT * FROM tblKeywordCategories WHERE id = " . (int) $id; + $queryStr = "SELECT * FROM `tblKeywordCategories` WHERE `id` = " . (int) $id; $resArr = $this->db->getResultArray($queryStr); if ((is_bool($resArr) && !$resArr) || (count($resArr) != 1)) return false; @@ -1393,7 +1379,7 @@ class SeedDMS_Core_DMS { } /* }}} */ function getKeywordCategoryByName($name, $userID) { /* {{{ */ - $queryStr = "SELECT * FROM tblKeywordCategories WHERE name = " . $this->db->qstr($name) . " AND owner = " . (int) $userID; + $queryStr = "SELECT * FROM `tblKeywordCategories` WHERE `name` = " . $this->db->qstr($name) . " AND `owner` = " . (int) $userID; $resArr = $this->db->getResultArray($queryStr); if ((is_bool($resArr) && !$resArr) || (count($resArr) != 1)) return false; @@ -1405,9 +1391,9 @@ class SeedDMS_Core_DMS { } /* }}} */ function getAllKeywordCategories($userIDs = array()) { /* {{{ */ - $queryStr = "SELECT * FROM tblKeywordCategories"; + $queryStr = "SELECT * FROM `tblKeywordCategories`"; if ($userIDs) - $queryStr .= " WHERE owner in (".implode(',', $userIDs).")"; + $queryStr .= " WHERE `owner` IN (".implode(',', $userIDs).")"; $resArr = $this->db->getResultArray($queryStr); if (is_bool($resArr) && !$resArr) @@ -1427,9 +1413,9 @@ class SeedDMS_Core_DMS { * This function should be replaced by getAllKeywordCategories() */ function getAllUserKeywordCategories($userID) { /* {{{ */ - $queryStr = "SELECT * FROM tblKeywordCategories"; + $queryStr = "SELECT * FROM `tblKeywordCategories`"; if ($userID != -1) - $queryStr .= " WHERE owner = " . (int) $userID; + $queryStr .= " WHERE `owner` = " . (int) $userID; $resArr = $this->db->getResultArray($queryStr); if (is_bool($resArr) && !$resArr) @@ -1449,7 +1435,7 @@ class SeedDMS_Core_DMS { if (is_object($this->getKeywordCategoryByName($name, $userID))) { return false; } - $queryStr = "INSERT INTO tblKeywordCategories (owner, name) VALUES (".(int) $userID.", ".$this->db->qstr($name).")"; + $queryStr = "INSERT INTO `tblKeywordCategories` (`owner`, `name`) VALUES (".(int) $userID.", ".$this->db->qstr($name).")"; if (!$this->db->getResult($queryStr)) return false; @@ -1470,7 +1456,7 @@ class SeedDMS_Core_DMS { if (!is_numeric($id)) return false; - $queryStr = "SELECT * FROM tblCategory WHERE id = " . (int) $id; + $queryStr = "SELECT * FROM `tblCategory` WHERE `id` = " . (int) $id; $resArr = $this->db->getResultArray($queryStr); if ((is_bool($resArr) && !$resArr) || (count($resArr) != 1)) return false; @@ -1482,7 +1468,7 @@ class SeedDMS_Core_DMS { } /* }}} */ function getDocumentCategories() { /* {{{ */ - $queryStr = "SELECT * FROM tblCategory order by name"; + $queryStr = "SELECT * FROM `tblCategory` order by `name`"; $resArr = $this->db->getResultArray($queryStr); if (is_bool($resArr) && !$resArr) @@ -1509,7 +1495,7 @@ class SeedDMS_Core_DMS { function getDocumentCategoryByName($name) { /* {{{ */ if (!$name) return false; - $queryStr = "SELECT * FROM tblCategory where name=".$this->db->qstr($name); + $queryStr = "SELECT * FROM `tblCategory` where `name`=".$this->db->qstr($name); $resArr = $this->db->getResultArray($queryStr); if (!$resArr) return false; @@ -1525,7 +1511,7 @@ class SeedDMS_Core_DMS { if (is_object($this->getDocumentCategoryByName($name))) { return false; } - $queryStr = "INSERT INTO tblCategory (name) VALUES (".$this->db->qstr($name).")"; + $queryStr = "INSERT INTO `tblCategory` (`name`) VALUES (".$this->db->qstr($name).")"; if (!$this->db->getResult($queryStr)) return false; @@ -1577,7 +1563,7 @@ class SeedDMS_Core_DMS { */ function createPasswordRequest($user) { /* {{{ */ $hash = md5(uniqid(time())); - $queryStr = "INSERT INTO tblUserPasswordRequest (userID, hash, `date`) VALUES (" . $user->getId() . ", " . $this->db->qstr($hash) .", ".$this->db->getCurrentDatetime().")"; + $queryStr = "INSERT INTO `tblUserPasswordRequest` (`userID`, `hash`, `date`) VALUES (" . $user->getId() . ", " . $this->db->qstr($hash) .", ".$this->db->getCurrentDatetime().")"; $resArr = $this->db->getResult($queryStr); if (is_bool($resArr) && !$resArr) return false; return $hash; @@ -1593,7 +1579,7 @@ class SeedDMS_Core_DMS { */ function checkPasswordRequest($hash) { /* {{{ */ /* Get the password request from the database */ - $queryStr = "SELECT * FROM tblUserPasswordRequest where hash=".$this->db->qstr($hash); + $queryStr = "SELECT * FROM `tblUserPasswordRequest` where `hash`=".$this->db->qstr($hash); $resArr = $this->db->getResultArray($queryStr); if (is_bool($resArr) && !$resArr) return false; @@ -1613,7 +1599,7 @@ class SeedDMS_Core_DMS { */ function deletePasswordRequest($hash) { /* {{{ */ /* Delete the request, so nobody can use it a second time */ - $queryStr = "DELETE FROM tblUserPasswordRequest WHERE hash=".$this->db->qstr($hash); + $queryStr = "DELETE FROM `tblUserPasswordRequest` WHERE `hash`=".$this->db->qstr($hash); if (!$this->db->getResult($queryStr)) return false; return true; @@ -1632,7 +1618,7 @@ class SeedDMS_Core_DMS { if (!is_numeric($id)) return false; - $queryStr = "SELECT * FROM tblAttributeDefinitions WHERE id = " . (int) $id; + $queryStr = "SELECT * FROM `tblAttributeDefinitions` WHERE `id` = " . (int) $id; $resArr = $this->db->getResultArray($queryStr); if (is_bool($resArr) && $resArr == false) return false; @@ -1656,7 +1642,7 @@ class SeedDMS_Core_DMS { function getAttributeDefinitionByName($name) { /* {{{ */ if (!$name) return false; - $queryStr = "SELECT * FROM tblAttributeDefinitions WHERE name = " . $this->db->qstr($name); + $queryStr = "SELECT * FROM `tblAttributeDefinitions` WHERE `name` = " . $this->db->qstr($name); $resArr = $this->db->getResultArray($queryStr); if (is_bool($resArr) && $resArr == false) return false; @@ -1676,14 +1662,14 @@ class SeedDMS_Core_DMS { * @return array of instances of {@link SeedDMS_Core_AttributeDefinition} or false */ function getAllAttributeDefinitions($objtype=0) { /* {{{ */ - $queryStr = "SELECT * FROM tblAttributeDefinitions"; + $queryStr = "SELECT * FROM `tblAttributeDefinitions`"; if($objtype) { if(is_array($objtype)) - $queryStr .= ' WHERE objtype in (\''.implode("','", $objtype).'\')'; + $queryStr .= ' WHERE `objtype` in (\''.implode("','", $objtype).'\')'; else - $queryStr .= ' WHERE objtype='.intval($objtype); + $queryStr .= ' WHERE `objtype`='.intval($objtype); } - $queryStr .= ' ORDER BY name'; + $queryStr .= ' ORDER BY `name`'; $resArr = $this->db->getResultArray($queryStr); if (is_bool($resArr) && $resArr == false) @@ -1723,7 +1709,7 @@ class SeedDMS_Core_DMS { } else { $valueset = ''; } - $queryStr = "INSERT INTO tblAttributeDefinitions (name, objtype, type, multiple, minvalues, maxvalues, valueset, regex) VALUES (".$this->db->qstr($name).", ".intval($objtype).", ".intval($type).", ".intval($multiple).", ".intval($minvalues).", ".intval($maxvalues).", ".$this->db->qstr($valueset).", ".$this->db->qstr($regex).")"; + $queryStr = "INSERT INTO `tblAttributeDefinitions` (`name`, `objtype`, `type`, `multiple`, `minvalues`, `maxvalues`, `valueset`, `regex`) VALUES (".$this->db->qstr($name).", ".intval($objtype).", ".intval($type).", ".intval($multiple).", ".intval($minvalues).", ".intval($maxvalues).", ".$this->db->qstr($valueset).", ".$this->db->qstr($regex).")"; $res = $this->db->getResult($queryStr); if (!$res) return false; @@ -1737,13 +1723,13 @@ class SeedDMS_Core_DMS { * @return array of instances of {@link SeedDMS_Core_Workflow} or false */ function getAllWorkflows() { /* {{{ */ - $queryStr = "SELECT * FROM tblWorkflows ORDER BY name"; + $queryStr = "SELECT * FROM `tblWorkflows` ORDER BY `name`"; $resArr = $this->db->getResultArray($queryStr); if (is_bool($resArr) && $resArr == false) return false; - $queryStr = "SELECT * FROM tblWorkflowStates ORDER BY name"; + $queryStr = "SELECT * FROM `tblWorkflowStates` ORDER BY `name`"; $ressArr = $this->db->getResultArray($queryStr); if (is_bool($ressArr) && $ressArr == false) @@ -1770,7 +1756,7 @@ class SeedDMS_Core_DMS { * @return object of instances of {@link SeedDMS_Core_Workflow} or false */ function getWorkflow($id) { /* {{{ */ - $queryStr = "SELECT * FROM tblWorkflows WHERE id=".intval($id); + $queryStr = "SELECT * FROM `tblWorkflows` WHERE `id`=".intval($id); $resArr = $this->db->getResultArray($queryStr); if (is_bool($resArr) && $resArr == false) @@ -1796,7 +1782,7 @@ class SeedDMS_Core_DMS { function getWorkflowByName($name) { /* {{{ */ if (!$name) return false; - $queryStr = "SELECT * FROM tblWorkflows WHERE name=".$this->db->qstr($name); + $queryStr = "SELECT * FROM `tblWorkflows` WHERE `name`=".$this->db->qstr($name); $resArr = $this->db->getResultArray($queryStr); if (is_bool($resArr) && $resArr == false) @@ -1824,7 +1810,7 @@ class SeedDMS_Core_DMS { if (is_object($this->getWorkflowByName($name))) { return false; } - $queryStr = "INSERT INTO tblWorkflows (name, initstate) VALUES (".$db->qstr($name).", ".$initstate->getID().")"; + $queryStr = "INSERT INTO `tblWorkflows` (`name`, `initstate`) VALUES (".$db->qstr($name).", ".$initstate->getID().")"; $res = $db->getResult($queryStr); if (!$res) return false; @@ -1844,7 +1830,7 @@ class SeedDMS_Core_DMS { if (!is_numeric($id)) return false; - $queryStr = "SELECT * FROM tblWorkflowStates WHERE id = " . (int) $id; + $queryStr = "SELECT * FROM `tblWorkflowStates` WHERE `id` = " . (int) $id; $resArr = $this->db->getResultArray($queryStr); if (is_bool($resArr) && $resArr == false) return false; @@ -1866,7 +1852,7 @@ class SeedDMS_Core_DMS { function getWorkflowStateByName($name) { /* {{{ */ if (!$name) return false; - $queryStr = "SELECT * FROM tblWorkflowStates WHERE name=".$this->db->qstr($name); + $queryStr = "SELECT * FROM `tblWorkflowStates` WHERE `name`=".$this->db->qstr($name); $resArr = $this->db->getResultArray($queryStr); if (is_bool($resArr) && $resArr == false) @@ -1889,7 +1875,7 @@ class SeedDMS_Core_DMS { * @return array of instances of {@link SeedDMS_Core_Workflow_State} or false */ function getAllWorkflowStates() { /* {{{ */ - $queryStr = "SELECT * FROM tblWorkflowStates ORDER BY name"; + $queryStr = "SELECT * FROM `tblWorkflowStates` ORDER BY `name`"; $ressArr = $this->db->getResultArray($queryStr); if (is_bool($ressArr) && $ressArr == false) @@ -1917,7 +1903,7 @@ class SeedDMS_Core_DMS { if (is_object($this->getWorkflowStateByName($name))) { return false; } - $queryStr = "INSERT INTO tblWorkflowStates (name, documentstatus) VALUES (".$db->qstr($name).", ".(int) $docstatus.")"; + $queryStr = "INSERT INTO `tblWorkflowStates` (`name`, `documentstatus`) VALUES (".$db->qstr($name).", ".(int) $docstatus.")"; $res = $db->getResult($queryStr); if (!$res) return false; @@ -1937,7 +1923,7 @@ class SeedDMS_Core_DMS { if (!is_numeric($id)) return false; - $queryStr = "SELECT * FROM tblWorkflowActions WHERE id = " . (int) $id; + $queryStr = "SELECT * FROM `tblWorkflowActions` WHERE `id` = " . (int) $id; $resArr = $this->db->getResultArray($queryStr); if (is_bool($resArr) && $resArr == false) return false; @@ -1961,7 +1947,7 @@ class SeedDMS_Core_DMS { function getWorkflowActionByName($name) { /* {{{ */ if (!$name) return false; - $queryStr = "SELECT * FROM tblWorkflowActions WHERE name = " . $this->db->qstr($name); + $queryStr = "SELECT * FROM `tblWorkflowActions` WHERE `name` = " . $this->db->qstr($name); $resArr = $this->db->getResultArray($queryStr); if (is_bool($resArr) && $resArr == false) return false; @@ -1980,7 +1966,7 @@ class SeedDMS_Core_DMS { * @return array list of instances of {@link SeedDMS_Core_Workflow_Action} or false */ function getAllWorkflowActions() { /* {{{ */ - $queryStr = "SELECT * FROM tblWorkflowActions"; + $queryStr = "SELECT * FROM `tblWorkflowActions`"; $resArr = $this->db->getResultArray($queryStr); if (is_bool($resArr) && $resArr == false) @@ -2007,7 +1993,7 @@ class SeedDMS_Core_DMS { if (is_object($this->getWorkflowActionByName($name))) { return false; } - $queryStr = "INSERT INTO tblWorkflowActions (name) VALUES (".$db->qstr($name).")"; + $queryStr = "INSERT INTO `tblWorkflowActions` (`name`) VALUES (".$db->qstr($name).")"; $res = $db->getResult($queryStr); if (!$res) return false; @@ -2027,7 +2013,7 @@ class SeedDMS_Core_DMS { if (!is_numeric($id)) return false; - $queryStr = "SELECT * FROM tblWorkflowTransitions WHERE id = " . (int) $id; + $queryStr = "SELECT * FROM `tblWorkflowTransitions` WHERE `id` = " . (int) $id; $resArr = $this->db->getResultArray($queryStr); if (is_bool($resArr) && $resArr == false) return false; @@ -2050,7 +2036,7 @@ class SeedDMS_Core_DMS { * the document is gone already. */ function getUnlinkedDocumentContent() { /* {{{ */ - $queryStr = "SELECT * FROM tblDocumentContent WHERE document NOT IN (SELECT id FROM tblDocuments)"; + $queryStr = "SELECT * FROM `tblDocumentContent` WHERE `document` NOT IN (SELECT id FROM `tblDocuments`)"; $resArr = $this->db->getResultArray($queryStr); if ($resArr === false) return false; @@ -2074,7 +2060,7 @@ class SeedDMS_Core_DMS { * in version 4.0.0 of SeedDMS for implementation of user quotas. */ function getNoFileSizeDocumentContent() { /* {{{ */ - $queryStr = "SELECT * FROM tblDocumentContent WHERE fileSize = 0 OR fileSize is null"; + $queryStr = "SELECT * FROM `tblDocumentContent` WHERE `fileSize` = 0 OR `fileSize` is null"; $resArr = $this->db->getResultArray($queryStr); if ($resArr === false) return false; @@ -2098,7 +2084,7 @@ class SeedDMS_Core_DMS { * in version 4.0.0 of SeedDMS for finding duplicates. */ function getNoChecksumDocumentContent() { /* {{{ */ - $queryStr = "SELECT * FROM tblDocumentContent WHERE checksum = '' OR checksum is null"; + $queryStr = "SELECT * FROM `tblDocumentContent` WHERE `checksum` = '' OR `checksum` is null"; $resArr = $this->db->getResultArray($queryStr); if ($resArr === false) return false; @@ -2122,7 +2108,7 @@ class SeedDMS_Core_DMS { * in version 4.0.0 of SeedDMS for finding duplicates. */ function getDuplicateDocumentContent() { /* {{{ */ - $queryStr = "SELECT a.*, b.id as dupid FROM tblDocumentContent a LEFT JOIN tblDocumentContent b ON a.checksum=b.checksum where a.id!=b.id ORDER by a.id"; + $queryStr = "SELECT a.*, b.`id` as dupid FROM `tblDocumentContent` a LEFT JOIN `tblDocumentContent` b ON a.`checksum`=b.`checksum` where a.`id`!=b.`id` ORDER by a.`id`"; $resArr = $this->db->getResultArray($queryStr); if (!$resArr) return false; @@ -2154,43 +2140,43 @@ class SeedDMS_Core_DMS { function getStatisticalData($type='') { /* {{{ */ switch($type) { case 'docsperuser': - $queryStr = "select b.fullname as `key`, count(owner) as total from tblDocuments a left join tblUsers b on a.owner=b.id group by owner"; + $queryStr = "select b.`fullName` as `key`, count(`owner`) as total from `tblDocuments` a left join `tblUsers` b on a.`owner`=b.`id` group by `owner`, b.`fullName`"; $resArr = $this->db->getResultArray($queryStr); if (!$resArr) return false; return $resArr; case 'docspermimetype': - $queryStr = "select b.mimeType as `key`, count(mimeType) as total from tblDocuments a left join tblDocumentContent b on a.id=b.document group by b.mimeType"; + $queryStr = "select b.`mimeType` as `key`, count(`mimeType`) as total from `tblDocuments` a left join `tblDocumentContent` b on a.`id`=b.`document` group by b.`mimeType`"; $resArr = $this->db->getResultArray($queryStr); if (!$resArr) return false; return $resArr; case 'docspercategory': - $queryStr = "select b.name as `key`, count(a.categoryID) as total from tblDocumentCategory a left join tblCategory b on a.categoryID=b.id group by a.categoryID"; + $queryStr = "select b.`name` as `key`, count(a.`categoryID`) as total from `tblDocumentCategory` a left join `tblCategory` b on a.`categoryID`=b.id group by a.`categoryID`, b.`name`"; $resArr = $this->db->getResultArray($queryStr); if (!$resArr) return false; return $resArr; case 'docsperstatus': - $queryStr = "select b.status as `key`, count(b.status) as total from (select a.id, max(b.version), max(c.statusLogId) as maxlog from tblDocuments a left join tblDocumentStatus b on a.id=b.documentid left join tblDocumentStatusLog c on b.statusid=c.statusid group by a.id, b.version order by a.id, b.statusid) a left join tblDocumentStatusLog b on a.maxlog=b.statusLogId group by b.status"; - $queryStr = "select b.status as `key`, count(b.status) as total from (select a.id, max(c.statusLogId) as maxlog from tblDocuments a left join tblDocumentStatus b on a.id=b.documentid left join tblDocumentStatusLog c on b.statusid=c.statusid group by a.id order by a.id, b.statusid) a left join tblDocumentStatusLog b on a.maxlog=b.statusLogId group by b.status"; + $queryStr = "select b.`status` as `key`, count(b.`status`) as total from (select a.id, max(b.version), max(c.`statusLogID`) as maxlog from `tblDocuments` a left join `tblDocumentStatus` b on a.id=b.`documentID` left join `tblDocumentStatusLog` c on b.`statusID`=c.`statusID` group by a.`id`, b.`version` order by a.`id`, b.`statusID`) a left join `tblDocumentStatusLog` b on a.`maxlog`=b.`statusLogID` group by b.`status`"; + $queryStr = "select b.`status` as `key`, count(b.`status`) as total from (select a.`id`, max(c.`statusLogID`) as maxlog from `tblDocuments` a left join `tblDocumentStatus` b on a.id=b.`documentID` left join `tblDocumentStatusLog` c on b.`statusID`=c.`statusID` group by a.`id` order by a.id) a left join `tblDocumentStatusLog` b on a.maxlog=b.`statusLogID` group by b.`status`"; $resArr = $this->db->getResultArray($queryStr); if (!$resArr) return false; return $resArr; case 'docspermonth': - $queryStr = "select *, count(`key`) as total from (select ".$this->db->getDateExtract("date", '%Y-%m')." as `key` from tblDocuments) a group by `key` order by `key`"; + $queryStr = "select *, count(`key`) as total from (select ".$this->db->getDateExtract("date", '%Y-%m')." as `key` from `tblDocuments`) a group by `key` order by `key`"; $resArr = $this->db->getResultArray($queryStr); if (!$resArr) return false; return $resArr; case 'docsaccumulated': - $queryStr = "select *, count(`key`) as total from (select ".$this->db->getDateExtract("date")." as `key` from tblDocuments) a group by `key` order by `key`"; + $queryStr = "select *, count(`key`) as total from (select ".$this->db->getDateExtract("date")." as `key` from `tblDocuments`) a group by `key` order by `key`"; $resArr = $this->db->getResultArray($queryStr); if (!$resArr) return false; @@ -2206,7 +2192,7 @@ class SeedDMS_Core_DMS { } return $resArr; case 'sizeperuser': - $queryStr = "select c.fullname as `key`, sum(fileSize) as total from tblDocuments a left join tblDocumentContent b on a.id=b.document left join tblUsers c on a.owner=c.id group by a.owner"; + $queryStr = "select c.`fullName` as `key`, sum(`fileSize`) as total from `tblDocuments` a left join `tblDocumentContent` b on a.id=b.`document` left join `tblUsers` c on a.`owner`=c.`id` group by a.`owner`, c.`fullName`"; $resArr = $this->db->getResultArray($queryStr); if (!$resArr) return false; @@ -2225,18 +2211,18 @@ class SeedDMS_Core_DMS { * entries in the database tables tblDocumentContent, tblDocumentFiles, * and tblDocumentStatusLog * - * @param string $start start date - * @param string $end end date + * @param string $start start date, defaults to start of current day + * @param string $end end date, defaults to end of start day * @return array list of changes */ function getTimeline($startts='', $endts='') { /* {{{ */ if(!$startts) $startts = mktime(0, 0, 0); if(!$endts) - $startts = mktime(24, 0, 0); + $endts = $startts+86400; $timeline = array(); - $queryStr = "SELECT document FROM tblDocumentContent WHERE date > ".$startts." AND date < ".$endts; + $queryStr = "SELECT DISTINCT document FROM `tblDocumentContent` WHERE `date` > ".$startts." AND `date` < ".$endts." UNION SELECT DISTINCT document FROM `tblDocumentFiles` WHERE `date` > ".$startts." AND `date` < ".$endts; $resArr = $this->db->getResultArray($queryStr); if ($resArr === false) return false; diff --git a/SeedDMS_Core/Core/inc.ClassDocument.php b/SeedDMS_Core/Core/inc.ClassDocument.php index f15b506e6..eb2a04e05 100644 --- a/SeedDMS_Core/Core/inc.ClassDocument.php +++ b/SeedDMS_Core/Core/inc.ClassDocument.php @@ -167,10 +167,41 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ $this->_notifyList = array(); } /* }}} */ + /** + * Return an array of database fields which used for searching + * a term entered in the database search form + * + * @param array $searchin integer list of search scopes (2=name, 3=comment, + * 4=attributes) + * @return array list of database fields + */ + public static function getSearchFields($searchin) { /* {{{ */ + $searchFields = array(); + if (in_array(1, $searchin)) { + $searchFields[] = "`tblDocuments`.`keywords`"; + } + if (in_array(2, $searchin)) { + $searchFields[] = "`tblDocuments`.`name`"; + } + if (in_array(3, $searchin)) { + $searchFields[] = "`tblDocuments`.`comment`"; + $searchFields[] = "`tblDocumentContent`.`comment`"; + } + if (in_array(4, $searchin)) { + $searchFields[] = "`tblDocumentAttributes`.`value`"; + $searchFields[] = "`tblDocumentContentAttributes`.`value`"; + } + if (in_array(5, $searchin)) { + $searchFields[] = "`tblDocuments`.`id`"; + } + + return $searchFields; + } /* }}} */ + public static function getInstance($id, $dms) { /* {{{ */ $db = $dms->getDB(); - $queryStr = "SELECT * FROM tblDocuments WHERE id = " . (int) $id; + $queryStr = "SELECT * FROM `tblDocuments` WHERE `id` = " . (int) $id; $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && $resArr == false) return false; @@ -179,7 +210,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ $resArr = $resArr[0]; // New Locking mechanism uses a separate table to track the lock. - $queryStr = "SELECT * FROM tblDocumentLocks WHERE document = " . (int) $id; + $queryStr = "SELECT * FROM `tblDocumentLocks` WHERE `document` = " . (int) $id; $lockArr = $db->getResultArray($queryStr); if ((is_bool($lockArr) && $lockArr==false) || (count($lockArr)==0)) { // Could not find a lock on the selected document. @@ -196,7 +227,6 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ return $document; } /* }}} */ - /* * Return the directory of the document in the file system relativ * to the contentDir @@ -227,7 +257,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ function setName($newName) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblDocuments SET name = ".$db->qstr($newName)." WHERE id = ". $this->_id; + $queryStr = "UPDATE `tblDocuments` SET `name` = ".$db->qstr($newName)." WHERE `id` = ". $this->_id; if (!$db->getResult($queryStr)) return false; @@ -250,7 +280,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ function setComment($newComment) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblDocuments SET comment = ".$db->qstr($newComment)." WHERE id = ". $this->_id; + $queryStr = "UPDATE `tblDocuments` SET `comment` = ".$db->qstr($newComment)." WHERE `id` = ". $this->_id; if (!$db->getResult($queryStr)) return false; @@ -263,7 +293,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ function setKeywords($newKeywords) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblDocuments SET keywords = ".$db->qstr($newKeywords)." WHERE id = ". $this->_id; + $queryStr = "UPDATE `tblDocuments` SET `keywords` = ".$db->qstr($newKeywords)." WHERE `id` = ". $this->_id; if (!$db->getResult($queryStr)) return false; @@ -280,7 +310,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ $db = $this->_dms->getDB(); if(!$this->_categories) { - $queryStr = "SELECT * FROM tblCategory where id in (select categoryID from tblDocumentCategory where documentID = ".$this->_id.")"; + $queryStr = "SELECT * FROM `tblCategory` where `id` in (select `categoryID` from `tblDocumentCategory` where `documentID` = ".$this->_id.")"; $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && !$resArr) return false; @@ -305,14 +335,14 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ $db = $this->_dms->getDB(); $db->startTransaction(); - $queryStr = "DELETE from tblDocumentCategory WHERE documentID = ". $this->_id; + $queryStr = "DELETE from `tblDocumentCategory` WHERE `documentID` = ". $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } foreach($newCategories as $cat) { - $queryStr = "INSERT INTO tblDocumentCategory (categoryID, documentID) VALUES (". $cat->getId() .", ". $this->_id .")"; + $queryStr = "INSERT INTO `tblDocumentCategory` (`categoryID`, `documentID`) VALUES (". $cat->getId() .", ". $this->_id .")"; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; @@ -350,7 +380,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ return false; } - $queryStr = "UPDATE tblDocuments SET date = " . (int) $date . " WHERE id = ". $this->_id; + $queryStr = "UPDATE `tblDocuments` SET `date` = " . (int) $date . " WHERE `id` = ". $this->_id; if (!$db->getResult($queryStr)) return false; $this->_date = $date; @@ -380,7 +410,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ function setFolder($newFolder) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblDocuments SET folder = " . $newFolder->getID() . " WHERE id = ". $this->_id; + $queryStr = "UPDATE `tblDocuments` SET `folder` = " . $newFolder->getID() . " WHERE `id` = ". $this->_id; if (!$db->getResult($queryStr)) return false; $this->_folderID = $newFolder->getID(); @@ -395,7 +425,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ if (strlen($flist)>1) { $flist .= ":"; } - $queryStr = "UPDATE tblDocuments SET folderList = '" . $flist . "' WHERE id = ". $this->_id; + $queryStr = "UPDATE `tblDocuments` SET `folderList` = '" . $flist . "' WHERE `id` = ". $this->_id; if (!$db->getResult($queryStr)) return false; @@ -422,7 +452,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ function setOwner($newOwner) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblDocuments set owner = " . $newOwner->getID() . " WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblDocuments` set `owner` = " . $newOwner->getID() . " WHERE `id` = " . $this->_id; if (!$db->getResult($queryStr)) return false; @@ -452,7 +482,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ function setDefaultAccess($mode, $noclean="false") { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblDocuments set defaultAccess = " . (int) $mode . " WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblDocuments` set `defaultAccess` = " . (int) $mode . " WHERE `id` = " . $this->_id; if (!$db->getResult($queryStr)) return false; @@ -483,7 +513,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ function setInheritAccess($inheritAccess, $noclean=false) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblDocuments SET inheritAccess = " . ($inheritAccess ? "1" : "0") . " WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblDocuments` SET `inheritAccess` = " . ($inheritAccess ? "1" : "0") . " WHERE `id` = " . $this->_id; if (!$db->getResult($queryStr)) return false; @@ -534,7 +564,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ return true; } - $queryStr = "UPDATE tblDocuments SET expires = " . (int) $expires . " WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblDocuments` SET `expires` = " . (int) $expires . " WHERE `id` = " . $this->_id; if (!$db->getResult($queryStr)) return false; @@ -599,10 +629,10 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ $lockUserID = -1; if (is_bool($falseOrUser) && !$falseOrUser) { - $queryStr = "DELETE FROM tblDocumentLocks WHERE document = ".$this->_id; + $queryStr = "DELETE FROM `tblDocumentLocks` WHERE `document` = ".$this->_id; } else if (is_object($falseOrUser)) { - $queryStr = "INSERT INTO tblDocumentLocks (document, userID) VALUES (".$this->_id.", ".$falseOrUser->getID().")"; + $queryStr = "INSERT INTO `tblDocumentLocks` (`document`, `userID`) VALUES (".$this->_id.", ".$falseOrUser->getID().")"; $lockUserID = $falseOrUser->getID(); } else { @@ -635,7 +665,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ function setSequence($seq) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblDocuments SET sequence = " . $seq . " WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblDocuments` SET `sequence` = " . $seq . " WHERE `id` = " . $this->_id; if (!$db->getResult($queryStr)) return false; @@ -652,7 +682,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ function clearAccessList($noclean=false) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "DELETE FROM tblACLs WHERE targetType = " . T_DOCUMENT . " AND target = " . $this->_id; + $queryStr = "DELETE FROM `tblACLs` WHERE `targetType` = " . T_DOCUMENT . " AND `target` = " . $this->_id; if (!$db->getResult($queryStr)) return false; @@ -699,8 +729,8 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ if ($mode!=M_ANY) { $modeStr = " AND mode".$op.(int)$mode; } - $queryStr = "SELECT * FROM tblACLs WHERE targetType = ".T_DOCUMENT. - " AND target = " . $this->_id . $modeStr . " ORDER BY targetType"; + $queryStr = "SELECT * FROM `tblACLs` WHERE `targetType` = ".T_DOCUMENT. + " AND target = " . $this->_id . $modeStr . " ORDER BY `targetType`"; $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && !$resArr) return false; @@ -730,9 +760,9 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ function addAccess($mode, $userOrGroupID, $isUser) { /* {{{ */ $db = $this->_dms->getDB(); - $userOrGroup = ($isUser) ? "userID" : "groupID"; + $userOrGroup = ($isUser) ? "`userID`" : "`groupID`"; - $queryStr = "INSERT INTO tblACLs (target, targetType, ".$userOrGroup.", mode) VALUES + $queryStr = "INSERT INTO `tblACLs` (`target`, `targetType`, ".$userOrGroup.", `mode`) VALUES (".$this->_id.", ".T_DOCUMENT.", " . (int) $userOrGroupID . ", " .(int) $mode. ")"; if (!$db->getResult($queryStr)) return false; @@ -760,9 +790,9 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ function changeAccess($newMode, $userOrGroupID, $isUser) { /* {{{ */ $db = $this->_dms->getDB(); - $userOrGroup = ($isUser) ? "userID" : "groupID"; + $userOrGroup = ($isUser) ? "`userID`" : "`groupID`"; - $queryStr = "UPDATE tblACLs SET mode = " . (int) $newMode . " WHERE targetType = ".T_DOCUMENT." AND target = " . $this->_id . " AND " . $userOrGroup . " = " . (int) $userOrGroupID; + $queryStr = "UPDATE `tblACLs` SET `mode` = " . (int) $newMode . " WHERE `targetType` = ".T_DOCUMENT." AND `target` = " . $this->_id . " AND " . $userOrGroup . " = " . (int) $userOrGroupID; if (!$db->getResult($queryStr)) return false; @@ -787,9 +817,9 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ function removeAccess($userOrGroupID, $isUser) { /* {{{ */ $db = $this->_dms->getDB(); - $userOrGroup = ($isUser) ? "userID" : "groupID"; + $userOrGroup = ($isUser) ? "`userID`" : "`groupID`"; - $queryStr = "DELETE FROM tblACLs WHERE targetType = ".T_DOCUMENT." AND target = ".$this->_id." AND ".$userOrGroup." = " . (int) $userOrGroupID; + $queryStr = "DELETE FROM `tblACLs` WHERE `targetType` = ".T_DOCUMENT." AND `target` = ".$this->_id." AND ".$userOrGroup." = " . (int) $userOrGroupID; if (!$db->getResult($queryStr)) return false; @@ -927,7 +957,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ if (empty($this->_notifyList)) { $db = $this->_dms->getDB(); - $queryStr ="SELECT * FROM tblNotify WHERE targetType = " . T_DOCUMENT . " AND target = " . $this->_id; + $queryStr ="SELECT * FROM `tblNotify` WHERE `targetType` = " . T_DOCUMENT . " AND `target` = " . $this->_id; $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && $resArr == false) return false; @@ -989,7 +1019,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ function addNotify($userOrGroupID, $isUser) { /* {{{ */ $db = $this->_dms->getDB(); - $userOrGroup = ($isUser ? "userID" : "groupID"); + $userOrGroup = ($isUser ? "`userID`" : "`groupID`"); /* Verify that user / group exists. */ $obj = ($isUser ? $this->_dms->getUser($userOrGroupID) : $this->_dms->getGroup($userOrGroupID)); @@ -1069,7 +1099,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ /* Check to see if user/group is already on the list. */ $queryStr = "SELECT * FROM `tblNotify` WHERE `tblNotify`.`target` = '".$this->_id."' ". "AND `tblNotify`.`targetType` = '".T_DOCUMENT."' ". - "AND `tblNotify`.`".$userOrGroup."` = '".(int) $userOrGroupID."'"; + "AND `tblNotify`.".$userOrGroup." = '".(int) $userOrGroupID."'"; $resArr = $db->getResultArray($queryStr); if (is_bool($resArr)) { return -4; @@ -1078,7 +1108,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ return -3; } - $queryStr = "INSERT INTO tblNotify (target, targetType, " . $userOrGroup . ") VALUES (" . $this->_id . ", " . T_DOCUMENT . ", " . (int) $userOrGroupID . ")"; + $queryStr = "INSERT INTO `tblNotify` (`target`, `targetType`, " . $userOrGroup . ") VALUES (" . $this->_id . ", " . T_DOCUMENT . ", " . (int) $userOrGroupID . ")"; if (!$db->getResult($queryStr)) return -4; @@ -1110,7 +1140,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ return -1; } - $userOrGroup = ($isUser) ? "userID" : "groupID"; + $userOrGroup = ($isUser) ? "`userID`" : "`groupID`"; /* Verify that the requesting user has permission to add the target to * the notification system. @@ -1141,7 +1171,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ /* Check to see if the target is in the database. */ $queryStr = "SELECT * FROM `tblNotify` WHERE `tblNotify`.`target` = '".$this->_id."' ". "AND `tblNotify`.`targetType` = '".T_DOCUMENT."' ". - "AND `tblNotify`.`".$userOrGroup."` = '".(int) $userOrGroupID."'"; + "AND `tblNotify`.".$userOrGroup." = '".(int) $userOrGroupID."'"; $resArr = $db->getResultArray($queryStr); if (is_bool($resArr)) { return -4; @@ -1150,7 +1180,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ return -3; } - $queryStr = "DELETE FROM tblNotify WHERE target = " . $this->_id . " AND targetType = " . T_DOCUMENT . " AND " . $userOrGroup . " = " . (int) $userOrGroupID; + $queryStr = "DELETE FROM `tblNotify` WHERE `target` = " . $this->_id . " AND `targetType` = " . T_DOCUMENT . " AND " . $userOrGroup . " = " . (int) $userOrGroupID; /* If type is given then delete only those notifications */ if($type) $queryStr .= " AND `type` = ".(int) $type; @@ -1193,7 +1223,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ * innodb is used. That's why the version is now determined here. */ if ((int)$version<1) { - $queryStr = "SELECT MAX(version) as m from tblDocumentContent where document = ".$this->_id; + $queryStr = "SELECT MAX(`version`) as m from `tblDocumentContent` where `document` = ".$this->_id; $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && !$res) return false; @@ -1205,7 +1235,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ $checksum = SeedDMS_Core_File::checksum($tmpFile); $db->startTransaction(); - $queryStr = "INSERT INTO tblDocumentContent (document, version, comment, date, createdBy, dir, orgFileName, fileType, mimeType, fileSize, checksum) VALUES ". + $queryStr = "INSERT INTO `tblDocumentContent` (`document`, `version`, `comment`, `date`, `createdBy`, `dir`, `orgFileName`, `fileType`, `mimeType`, `fileSize`, `checksum`) VALUES ". "(".$this->_id.", ".(int)$version.",".$db->qstr($comment).", ".$db->getCurrentTimestamp().", ".$user->getID().", ".$db->qstr($dir).", ".$db->qstr($orgFileName).", ".$db->qstr($fileType).", ".$db->qstr($mimeType).", ".$filesize.", ".$db->qstr($checksum).")"; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); @@ -1231,9 +1261,6 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ unset($this->_content); unset($this->_latestContent); $content = $this->getLatestContent($contentID); -// $content = new SeedDMS_Core_DocumentContent($contentID, $this, $version, $comment, $date, $user->getID(), $dir, $orgFileName, $fileType, $mimeType, $filesize, $checksum); - if($workflow) - $content->setWorkflow($workflow, $user); $docResultSet = new SeedDMS_Core_AddContentResultSet($content); $docResultSet->setDMS($this->_dms); @@ -1263,6 +1290,9 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ $statusID = $db->getInsertID(); + if($workflow) + $content->setWorkflow($workflow, $user); + // Add reviewers into the database. Reviewers must review the document // and submit comments, if appropriate. Reviewers can also recommend that // a document be rejected. @@ -1359,7 +1389,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ /* If $version < 1 than replace the content of the latest version. */ if ((int) $version<1) { - $queryStr = "SELECT MAX(version) as m from tblDocumentContent where document = ".$this->_id; + $queryStr = "SELECT MAX(`version`) as m from `tblDocumentContent` where `document` = ".$this->_id; $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && !$res) return false; @@ -1389,7 +1419,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ $checksum = SeedDMS_Core_File::checksum($tmpFile); $db->startTransaction(); - $queryStr = "UPDATE tblDocumentContent set date=".$db->getCurrentTimestamp().", fileSize=".$filesize.", checksum=".$db->qstr($checksum)." WHERE id=".$content->getID(); + $queryStr = "UPDATE `tblDocumentContent` set `date`=".$db->getCurrentTimestamp().", `fileSize`=".$filesize.", `checksum`=".$db->qstr($checksum)." WHERE `id`=".$content->getID(); if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; @@ -1419,7 +1449,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ $db = $this->_dms->getDB(); if (!isset($this->_content)) { - $queryStr = "SELECT * FROM tblDocumentContent WHERE document = ".$this->_id." ORDER BY version"; + $queryStr = "SELECT * FROM `tblDocumentContent` WHERE `document` = ".$this->_id." ORDER BY `version`"; $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && !$res) return false; @@ -1451,7 +1481,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ } $db = $this->_dms->getDB(); - $queryStr = "SELECT * FROM tblDocumentContent WHERE document = ".$this->_id." AND version = " . (int) $version; + $queryStr = "SELECT * FROM `tblDocumentContent` WHERE `document` = ".$this->_id." AND `version` = " . (int) $version; $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && !$res) return false; @@ -1466,7 +1496,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ function getLatestContent() { /* {{{ */ if (!isset($this->_latestContent)) { $db = $this->_dms->getDB(); - $queryStr = "SELECT * FROM tblDocumentContent WHERE document = ".$this->_id." ORDER BY version DESC LIMIT 0,1"; + $queryStr = "SELECT * FROM `tblDocumentContent` WHERE `document` = ".$this->_id." ORDER BY `version` DESC LIMIT 1"; $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && !$resArr) return false; @@ -1492,13 +1522,13 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ $status = $version->getStatus(); $stID = $status["statusID"]; - $queryStr = "DELETE FROM tblDocumentContent WHERE `document` = " . $this->getID() . " AND `version` = " . $version->_version; + $queryStr = "DELETE FROM `tblDocumentContent` WHERE `document` = " . $this->getID() . " AND `version` = " . $version->_version; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } - $queryStr = "DELETE FROM tblDocumentContentAttributes WHERE content = " . $version->getId(); + $queryStr = "DELETE FROM `tblDocumentContentAttributes` WHERE `content` = " . $version->getId(); if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; @@ -1520,7 +1550,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ $stList = ""; foreach ($status as $st) { $stList .= (strlen($stList)==0 ? "" : ", "). "'".$st["reviewID"]."'"; - $queryStr = "SELECT * FROM tblDocumentReviewLog WHERE reviewID = " . $st['reviewID']; + $queryStr = "SELECT * FROM `tblDocumentReviewLog` WHERE `reviewID` = " . $st['reviewID']; $resArr = $db->getResultArray($queryStr); if ((is_bool($resArr) && !$resArr)) { $db->rollbackTransaction(); @@ -1549,7 +1579,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ $stList = ""; foreach ($status as $st) { $stList .= (strlen($stList)==0 ? "" : ", "). "'".$st["approveID"]."'"; - $queryStr = "SELECT * FROM tblDocumentApproveLog WHERE approveID = " . $st['approveID']; + $queryStr = "SELECT * FROM `tblDocumentApproveLog` WHERE `approveID` = " . $st['approveID']; $resArr = $db->getResultArray($queryStr); if ((is_bool($resArr) && !$resArr)) { $db->rollbackTransaction(); @@ -1603,7 +1633,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ if (!is_numeric($linkID)) return false; - $queryStr = "SELECT * FROM tblDocumentLinks WHERE document = " . $this->_id ." AND id = " . (int) $linkID; + $queryStr = "SELECT * FROM `tblDocumentLinks` WHERE `document` = " . $this->_id ." AND `id` = " . (int) $linkID; $resArr = $db->getResultArray($queryStr); if ((is_bool($resArr) && !$resArr) || count($resArr)==0) return false; @@ -1631,12 +1661,12 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ if (!isset($this->_documentLinks)) { $db = $this->_dms->getDB(); - $queryStr = "SELECT * FROM tblDocumentLinks WHERE document = " . $this->_id; + $queryStr = "SELECT * FROM `tblDocumentLinks` WHERE `document` = " . $this->_id; $tmp = array(); if($publiconly) - $tmp[] = "public=1"; + $tmp[] = "`public`=1"; if($user) - $tmp[] = "userID=".$user->getID(); + $tmp[] = "`userID`=".$user->getID(); if($tmp) { $queryStr .= " AND (".implode(" OR ", $tmp).")"; } @@ -1675,12 +1705,12 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ function getReverseDocumentLinks($publiconly=false, $user=null) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "SELECT * FROM tblDocumentLinks WHERE target = " . $this->_id; + $queryStr = "SELECT * FROM `tblDocumentLinks` WHERE `target` = " . $this->_id; $tmp = array(); if($publiconly) - $tmp[] = "public=1"; + $tmp[] = "`public`=1"; if($user) - $tmp[] = "userID=".$user->getID(); + $tmp[] = "`userID`=".$user->getID(); if($tmp) { $queryStr .= " AND (".implode(" OR ", $tmp).")"; } @@ -1703,7 +1733,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ $public = ($public) ? "1" : "0"; - $queryStr = "INSERT INTO tblDocumentLinks(document, target, userID, public) VALUES (".$this->_id.", ".(int)$targetID.", ".(int)$userID.", ".(int)$public.")"; + $queryStr = "INSERT INTO `tblDocumentLinks` (`document`, `target`, `userID`, `public`) VALUES (".$this->_id.", ".(int)$targetID.", ".(int)$userID.", ".(int)$public.")"; if (!$db->getResult($queryStr)) return false; @@ -1716,7 +1746,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ if (!is_numeric($linkID)) return false; - $queryStr = "DELETE FROM tblDocumentLinks WHERE document = " . $this->_id ." AND id = " . (int) $linkID; + $queryStr = "DELETE FROM `tblDocumentLinks` WHERE `document` = " . $this->_id ." AND `id` = " . (int) $linkID; if (!$db->getResult($queryStr)) return false; unset ($this->_documentLinks); return true; @@ -1727,7 +1757,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ if (!is_numeric($ID)) return false; - $queryStr = "SELECT * FROM tblDocumentFiles WHERE document = " . $this->_id ." AND id = " . (int) $ID; + $queryStr = "SELECT * FROM `tblDocumentFiles` WHERE `document` = " . $this->_id ." AND `id` = " . (int) $ID; $resArr = $db->getResultArray($queryStr); if ((is_bool($resArr) && !$resArr) || count($resArr)==0) return false; @@ -1739,7 +1769,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ if (!isset($this->_documentFiles)) { $db = $this->_dms->getDB(); - $queryStr = "SELECT * FROM tblDocumentFiles WHERE document = " . $this->_id." ORDER BY `date` DESC"; + $queryStr = "SELECT * FROM `tblDocumentFiles` WHERE `document` = " . $this->_id." ORDER BY `date` DESC"; $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && !$resArr) return false; @@ -1757,7 +1787,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ $dir = $this->getDir(); - $queryStr = "INSERT INTO tblDocumentFiles (comment, date, dir, document, fileType, mimeType, orgFileName, userID, name) VALUES ". + $queryStr = "INSERT INTO `tblDocumentFiles` (`comment`, `date`, `dir`, `document`, `fileType`, `mimeType`, `orgFileName`, `userID`, `name`) VALUES ". "(".$db->qstr($comment).", ".$db->getCurrentTimestamp().", ".$db->qstr($dir).", ".$this->_id.", ".$db->qstr($fileType).", ".$db->qstr($mimeType).", ".$db->qstr($orgFileName).",".$user->getID().",".$db->qstr($name).")"; if (!$db->getResult($queryStr)) return false; @@ -1793,7 +1823,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ $name=$file->getName(); $comment=$file->getcomment(); - $queryStr = "DELETE FROM tblDocumentFiles WHERE document = " . $this->getID() . " AND id = " . (int) $ID; + $queryStr = "DELETE FROM `tblDocumentFiles` WHERE `document` = " . $this->getID() . " AND `id` = " . (int) $ID; if (!$db->getResult($queryStr)) return false; @@ -1861,44 +1891,44 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ return false; } - $queryStr = "DELETE FROM tblDocuments WHERE id = " . $this->_id; + $queryStr = "DELETE FROM `tblDocuments` WHERE `id` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } - $queryStr = "DELETE FROM tblDocumentAttributes WHERE document = " . $this->_id; + $queryStr = "DELETE FROM `tblDocumentAttributes` WHERE `document` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } - $queryStr = "DELETE FROM tblACLs WHERE target = " . $this->_id . " AND targetType = " . T_DOCUMENT; + $queryStr = "DELETE FROM `tblACLs` WHERE `target` = " . $this->_id . " AND `targetType` = " . T_DOCUMENT; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } - $queryStr = "DELETE FROM tblDocumentLinks WHERE document = " . $this->_id . " OR target = " . $this->_id; + $queryStr = "DELETE FROM `tblDocumentLinks` WHERE `document` = " . $this->_id . " OR `target` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } - $queryStr = "DELETE FROM tblDocumentLocks WHERE document = " . $this->_id; + $queryStr = "DELETE FROM `tblDocumentLocks` WHERE `document` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } - $queryStr = "DELETE FROM tblDocumentFiles WHERE document = " . $this->_id; + $queryStr = "DELETE FROM `tblDocumentFiles` WHERE `document` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } - $queryStr = "DELETE FROM tblDocumentCategory WHERE documentID = " . $this->_id; + $queryStr = "DELETE FROM `tblDocumentCategory` WHERE `documentID` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } // Delete the notification list. - $queryStr = "DELETE FROM tblNotify WHERE target = " . $this->_id . " AND targetType = " . T_DOCUMENT; + $queryStr = "DELETE FROM `tblNotify` WHERE `target` = " . $this->_id . " AND `targetType` = " . T_DOCUMENT; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; @@ -2066,7 +2096,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ function getFolderList() { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "SELECT folderList FROM tblDocuments where id = ".$this->_id; + $queryStr = "SELECT `folderList` FROM `tblDocuments` where id = ".$this->_id; $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && !$resArr) return false; @@ -2096,7 +2126,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ $pathPrefix .= ":"; } if($curfolderlist != $pathPrefix) { - $queryStr = "UPDATE tblDocuments SET folderList='".$pathPrefix."' WHERE id = ". $this->_id; + $queryStr = "UPDATE `tblDocuments` SET `folderList`='".$pathPrefix."' WHERE `id` = ". $this->_id; $res = $db->getResult($queryStr); if (!$res) return false; @@ -2115,7 +2145,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ function getUsedDiskSpace() { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "SELECT SUM(filesize) sum FROM tblDocumentContent WHERE document = " . $this->_id; + $queryStr = "SELECT SUM(`fileSize`) sum FROM `tblDocumentContent` WHERE `document` = " . $this->_id; $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && $resArr == false) return false; @@ -2137,7 +2167,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ /* No need to add entries for new version because the status log * will generate an entry as well. - $queryStr = "SELECT * FROM tblDocumentContent WHERE document = " . $this->_id; + $queryStr = "SELECT * FROM `tblDocumentContent` WHERE `document` = " . $this->_id; $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && $resArr == false) return false; @@ -2148,7 +2178,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ } */ - $queryStr = "SELECT * FROM tblDocumentFiles WHERE document = " . $this->_id; + $queryStr = "SELECT * FROM `tblDocumentFiles` WHERE `document` = " . $this->_id; $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && $resArr == false) return false; @@ -2317,7 +2347,7 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */ return false; } - $queryStr = "UPDATE tblDocumentContent SET date = ".(int) $date." WHERE `document` = " . $this->_document->getID() . " AND `version` = " . $this->_version; + $queryStr = "UPDATE `tblDocumentContent` SET `date` = ".(int) $date." WHERE `document` = " . $this->_document->getID() . " AND `version` = " . $this->_version; if (!$db->getResult($queryStr)) return false; @@ -2339,7 +2369,7 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */ return false; $db = $this->_document->_dms->getDB(); - $queryStr = "UPDATE tblDocumentContent SET fileSize = ".$filesize." where `document` = " . $this->_document->getID() . " AND `version` = " . $this->_version; + $queryStr = "UPDATE `tblDocumentContent` SET `fileSize` = ".$filesize." where `document` = " . $this->_document->getID() . " AND `version` = " . $this->_version; if (!$db->getResult($queryStr)) return false; $this->_fileSize = $filesize; @@ -2360,7 +2390,7 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */ return false; $db = $this->_document->_dms->getDB(); - $queryStr = "UPDATE tblDocumentContent SET checksum = ".$db->qstr($checksum)." where `document` = " . $this->_document->getID() . " AND `version` = " . $this->_version; + $queryStr = "UPDATE `tblDocumentContent` SET `checksum` = ".$db->qstr($checksum)." where `document` = " . $this->_document->getID() . " AND `version` = " . $this->_version; if (!$db->getResult($queryStr)) return false; $this->_checksum = $checksum; @@ -2371,7 +2401,7 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */ function setComment($newComment) { /* {{{ */ $db = $this->_document->_dms->getDB(); - $queryStr = "UPDATE tblDocumentContent SET comment = ".$db->qstr($newComment)." WHERE `document` = " . $this->_document->getID() . " AND `version` = " . $this->_version; + $queryStr = "UPDATE `tblDocumentContent` SET `comment` = ".$db->qstr($newComment)." WHERE `document` = " . $this->_document->getID() . " AND `version` = " . $this->_version; if (!$db->getResult($queryStr)) return false; @@ -2673,7 +2703,7 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */ if (1 || !isset($this->_reviewStatus)) { /* First get a list of all reviews for this document content */ $queryStr= - "SELECT reviewID FROM tblDocumentReviewers WHERE `version`='".$this->_version + "SELECT `reviewID` FROM `tblDocumentReviewers` WHERE `version`='".$this->_version ."' AND `documentID` = '". $this->_document->getID() ."' "; $recs = $db->getResultArray($queryStr); if (is_bool($recs) && !$recs) @@ -2801,7 +2831,7 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */ if (1 || !isset($this->_approvalStatus)) { /* First get a list of all approvals for this document content */ $queryStr= - "SELECT approveID FROM tblDocumentApprovers WHERE `version`='".$this->_version + "SELECT `approveID` FROM `tblDocumentApprovers` WHERE `version`='".$this->_version ."' AND `documentID` = '". $this->_document->getID() ."' "; $recs = $db->getResultArray($queryStr); if (is_bool($recs) && !$recs) @@ -3504,7 +3534,7 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */ $db = $this->_document->_dms->getDB(); if($this->_workflow) { - $queryStr = "UPDATE tblWorkflowDocumentContent set state=". $state->getID() ." WHERE workflow=". intval($this->_workflow->getID()). " AND document=". intval($this->_document->getID()) ." AND version=". intval($this->_version) .""; + $queryStr = "UPDATE `tblWorkflowDocumentContent` set `state`=". $state->getID() ." WHERE `workflow`=". intval($this->_workflow->getID()). " AND `document`=". intval($this->_document->getID()) ." AND version=". intval($this->_version) .""; if (!$db->getResult($queryStr)) { return false; } @@ -3531,9 +3561,9 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */ if (!$this->_workflowState) { $queryStr= - "SELECT b.* FROM tblWorkflowDocumentContent a LEFT JOIN tblWorkflowStates b ON a.state = b.id WHERE workflow=". intval($this->_workflow->getID()) - ." AND a.version='".$this->_version - ."' AND a.document = '". $this->_document->getID() ."' "; + "SELECT b.* FROM `tblWorkflowDocumentContent` a LEFT JOIN `tblWorkflowStates` b ON a.`state` = b.id WHERE `workflow`=". intval($this->_workflow->getID()) + ." AND a.`version`='".$this->_version + ."' AND a.`document` = '". $this->_document->getID() ."' "; $recs = $db->getResultArray($queryStr); if (is_bool($recs) && !$recs) return false; @@ -3555,7 +3585,7 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */ if($workflow && is_object($workflow)) { $db->startTransaction(); $initstate = $workflow->getInitState(); - $queryStr = "INSERT INTO tblWorkflowDocumentContent (workflow, document, version, state, date) VALUES (". $workflow->getID(). ", ". $this->_document->getID() .", ". $this->_version .", ".$initstate->getID().", ".$db->getCurrentDatetime().")"; + $queryStr = "INSERT INTO `tblWorkflowDocumentContent` (`workflow`, `document`, `version`, `state`, `date`) VALUES (". $workflow->getID(). ", ". $this->_document->getID() .", ". $this->_version .", ".$initstate->getID().", ".$db->getCurrentDatetime().")"; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; @@ -3586,9 +3616,9 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */ if (!isset($this->_workflow)) { $queryStr= - "SELECT b.* FROM tblWorkflowDocumentContent a LEFT JOIN tblWorkflows b ON a.workflow = b.id WHERE a.`version`='".$this->_version + "SELECT b.* FROM `tblWorkflowDocumentContent` a LEFT JOIN `tblWorkflows` b ON a.`workflow` = b.id WHERE a.`version`='".$this->_version ."' AND a.`document` = '". $this->_document->getID() ."' " - ." ORDER BY date DESC LIMIT 1"; + ." ORDER BY `date` DESC LIMIT 1"; $recs = $db->getResultArray($queryStr); if (is_bool($recs) && !$recs) return false; @@ -3657,7 +3687,7 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */ } $db->startTransaction(); - $queryStr = "DELETE from tblWorkflowLog WHERE `document` = ". $this->_document->getID() ." AND `version` = ".$this->_version." AND `workflow` = ".$this->_workflow->getID(); + $queryStr = "DELETE from `tblWorkflowLog` WHERE `document` = ". $this->_document->getID() ." AND `version` = ".$this->_version." AND `workflow` = ".$this->_workflow->getID(); if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; @@ -3700,7 +3730,7 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */ if(SeedDMS_Core_DMS::checkIfEqual($this->_workflow->getInitState(), $this->getWorkflowState()) || $unlink == true) { $db->startTransaction(); $queryStr= - "DELETE FROM tblWorkflowDocumentContent WHERE " + "DELETE FROM `tblWorkflowDocumentContent` WHERE " ."`version`='".$this->_version."' " ." AND `document` = '". $this->_document->getID() ."' " ." AND `workflow` = '". $this->_workflow->getID() ."' "; @@ -3710,7 +3740,7 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */ } if(!$unlink) { $queryStr= - "DELETE FROM tblWorkflowLog WHERE " + "DELETE FROM `tblWorkflowLog` WHERE " ."`version`='".$this->_version."' " ." AND `document` = '". $this->_document->getID() ."' " ." AND `workflow` = '". $this->_workflow->getID() ."' "; @@ -3742,7 +3772,7 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */ return false; $queryStr= - "SELECT * FROM tblWorkflowDocumentContent WHERE " + "SELECT * FROM `tblWorkflowDocumentContent` WHERE " ."`version`='".$this->_version."' " ." AND `document` = '". $this->_document->getID() ."' " ." AND `workflow` = '". $this->_workflow->getID() ."' "; @@ -3777,7 +3807,7 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */ if($subworkflow) { $initstate = $subworkflow->getInitState(); - $queryStr = "INSERT INTO tblWorkflowDocumentContent (parentworkflow, workflow, document, version, state, date) VALUES (". $this->_workflow->getID(). ", ". $subworkflow->getID(). ", ". $this->_document->getID() .", ". $this->_version .", ".$initstate->getID().", ".$db->getCurrentDatetime().")"; + $queryStr = "INSERT INTO `tblWorkflowDocumentContent` (`parentworkflow`, `workflow`, `document`, `version`, `state`, `date`) VALUES (". $this->_workflow->getID(). ", ". $subworkflow->getID(). ", ". $this->_document->getID() .", ". $this->_version .", ".$initstate->getID().", ".$db->getCurrentDatetime().")"; if (!$db->getResult($queryStr)) { return false; } @@ -3809,7 +3839,7 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */ $db->startTransaction(); $queryStr= - "SELECT * FROM tblWorkflowDocumentContent WHERE workflow=". intval($this->_workflow->getID()) + "SELECT * FROM `tblWorkflowDocumentContent` WHERE `workflow`=". intval($this->_workflow->getID()) . " AND `version`='".$this->_version ."' AND `document` = '". $this->_document->getID() ."' "; $recs = $db->getResultArray($queryStr); @@ -3868,7 +3898,7 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */ /* Check if the user has already triggered the transition */ $queryStr= - "SELECT * FROM tblWorkflowLog WHERE `version`='".$this->_version ."' AND `document` = '". $this->_document->getID() ."' AND `workflow` = ". $this->_workflow->getID(). " AND userid = ".$user->getID(); + "SELECT * FROM `tblWorkflowLog` WHERE `version`='".$this->_version ."' AND `document` = '". $this->_document->getID() ."' AND `workflow` = ". $this->_workflow->getID(). " AND userid = ".$user->getID(); $queryStr .= " AND `transition` = ".$transition->getID(); $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && !$resArr) @@ -4017,7 +4047,7 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */ return false; $state = $this->_workflowState; - $queryStr = "INSERT INTO tblWorkflowLog (document, version, workflow, userid, transition, date, comment) VALUES (".$this->_document->getID().", ".$this->_version.", " . (int) $this->_workflow->getID() . ", " .(int) $user->getID(). ", ".(int) $transition->getID().", ".$db->getCurrentDatetime().", ".$db->qstr($comment).")"; + $queryStr = "INSERT INTO `tblWorkflowLog` (`document`, `version`, `workflow`, `userid`, `transition`, `date`, `comment`) VALUES (".$this->_document->getID().", ".$this->_version.", " . (int) $this->_workflow->getID() . ", " .(int) $user->getID(). ", ".(int) $transition->getID().", ".$db->getCurrentDatetime().", ".$db->qstr($comment).")"; if (!$db->getResult($queryStr)) return false; @@ -4148,7 +4178,7 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */ return false; */ $queryStr= - "SELECT * FROM tblWorkflowLog WHERE `version`='".$this->_version ."' AND `document` = '". $this->_document->getID() ."'"; // AND `workflow` = ". $this->_workflow->getID(); + "SELECT * FROM `tblWorkflowLog` WHERE `version`='".$this->_version ."' AND `document` = '". $this->_document->getID() ."'"; // AND `workflow` = ". $this->_workflow->getID(); if($transition) $queryStr .= " AND `transition` = ".$transition->getID(); $queryStr .= " ORDER BY `date`"; @@ -4183,7 +4213,7 @@ class SeedDMS_Core_DocumentContent extends SeedDMS_Core_Object { /* {{{ */ return false; $queryStr= - "SELECT * FROM tblWorkflowLog WHERE `version`='".$this->_version ."' AND `document` = '". $this->_document->getID() ."' AND `workflow` = ". $this->_workflow->getID(); + "SELECT * FROM `tblWorkflowLog` WHERE `version`='".$this->_version ."' AND `document` = '". $this->_document->getID() ."' AND `workflow` = ". $this->_workflow->getID(); $queryStr .= " ORDER BY `id` DESC LIMIT 1"; $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && !$resArr) diff --git a/SeedDMS_Core/Core/inc.ClassDocumentCategory.php b/SeedDMS_Core/Core/inc.ClassDocumentCategory.php index f9e263a5c..76011efd0 100644 --- a/SeedDMS_Core/Core/inc.ClassDocumentCategory.php +++ b/SeedDMS_Core/Core/inc.ClassDocumentCategory.php @@ -56,7 +56,7 @@ class SeedDMS_Core_DocumentCategory { function setName($newName) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblCategory SET name = ".$db->qstr($newName)." WHERE id = ". $this->_id; + $queryStr = "UPDATE `tblCategory` SET `name` = ".$db->qstr($newName)." WHERE `id` = ". $this->_id; if (!$db->getResult($queryStr)) return false; @@ -67,7 +67,7 @@ class SeedDMS_Core_DocumentCategory { function isUsed() { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "SELECT * FROM tblDocumentCategory WHERE categoryID=".$this->_id; + $queryStr = "SELECT * FROM `tblDocumentCategory` WHERE `categoryID`=".$this->_id; $resArr = $db->getResultArray($queryStr); if (is_array($resArr) && count($resArr) == 0) return false; @@ -77,21 +77,21 @@ class SeedDMS_Core_DocumentCategory { function getCategories() { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "SELECT * FROM tblCategory"; + $queryStr = "SELECT * FROM `tblCategory`"; return $db->getResultArray($queryStr); } /* }}} */ function addCategory($keywords) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "INSERT INTO tblCategory (category) VALUES (".$db->qstr($keywords).")"; + $queryStr = "INSERT INTO `tblCategory` (`category`) VALUES (".$db->qstr($keywords).")"; return $db->getResult($queryStr); } /* }}} */ function remove() { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "DELETE FROM tblCategory WHERE id = " . $this->_id; + $queryStr = "DELETE FROM `tblCategory` WHERE `id` = " . $this->_id; if (!$db->getResult($queryStr)) return false; @@ -101,7 +101,7 @@ class SeedDMS_Core_DocumentCategory { function getDocumentsByCategory() { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "SELECT * FROM tblDocumentCategory where categoryID=".$this->_id; + $queryStr = "SELECT * FROM `tblDocumentCategory` where `categoryID`=".$this->_id; $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && !$resArr) return false; diff --git a/SeedDMS_Core/Core/inc.ClassFolder.php b/SeedDMS_Core/Core/inc.ClassFolder.php index b04d5c516..42c992d5c 100644 --- a/SeedDMS_Core/Core/inc.ClassFolder.php +++ b/SeedDMS_Core/Core/inc.ClassFolder.php @@ -126,7 +126,7 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object { public static function getInstance($id, $dms) { /* {{{ */ $db = $dms->getDB(); - $queryStr = "SELECT * FROM tblFolders WHERE id = " . (int) $id; + $queryStr = "SELECT * FROM `tblFolders` WHERE `id` = " . (int) $id; $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && $resArr == false) return false; @@ -155,7 +155,7 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object { public function setName($newName) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblFolders SET name = " . $db->qstr($newName) . " WHERE id = ". $this->_id; + $queryStr = "UPDATE `tblFolders` SET `name` = " . $db->qstr($newName) . " WHERE `id` = ". $this->_id; if (!$db->getResult($queryStr)) return false; @@ -169,7 +169,7 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object { public function setComment($newComment) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblFolders SET comment = " . $db->qstr($newComment) . " WHERE id = ". $this->_id; + $queryStr = "UPDATE `tblFolders` SET `comment` = " . $db->qstr($newComment) . " WHERE `id` = ". $this->_id; if (!$db->getResult($queryStr)) return false; @@ -203,7 +203,7 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object { return false; } - $queryStr = "UPDATE tblFolders SET date = " . (int) $date . " WHERE id = ". $this->_id; + $queryStr = "UPDATE `tblFolders` SET `date` = " . (int) $date . " WHERE `id` = ". $this->_id; if (!$db->getResult($queryStr)) return false; $this->_date = $date; @@ -276,7 +276,7 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object { if (strlen($pathPrefix)>1) { $pathPrefix .= ":"; } - $queryStr = "UPDATE tblFolders SET parent = ".$newParent->getID().", folderList='".$pathPrefix."' WHERE id = ". $this->_id; + $queryStr = "UPDATE `tblFolders` SET `parent` = ".$newParent->getID().", `folderList`='".$pathPrefix."' WHERE `id` = ". $this->_id; $res = $db->getResult($queryStr); if (!$res) return false; @@ -342,7 +342,7 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object { function setOwner($newOwner) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblFolders set owner = " . $newOwner->getID() . " WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblFolders` set `owner` = " . $newOwner->getID() . " WHERE `id` = " . $this->_id; if (!$db->getResult($queryStr)) return false; @@ -373,7 +373,7 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object { function setDefaultAccess($mode, $noclean=false) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblFolders set defaultAccess = " . (int) $mode . " WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblFolders` set `defaultAccess` = " . (int) $mode . " WHERE `id` = " . $this->_id; if (!$db->getResult($queryStr)) return false; @@ -406,7 +406,7 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object { $inheritAccess = ($inheritAccess) ? "1" : "0"; - $queryStr = "UPDATE tblFolders SET inheritAccess = " . (int) $inheritAccess . " WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblFolders` SET `inheritAccess` = " . (int) $inheritAccess . " WHERE `id` = " . $this->_id; if (!$db->getResult($queryStr)) return false; @@ -423,7 +423,7 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object { function setSequence($seq) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblFolders SET sequence = " . $seq . " WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblFolders` SET `sequence` = " . $seq . " WHERE `id` = " . $this->_id; if (!$db->getResult($queryStr)) return false; @@ -443,7 +443,7 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object { if (isset($this->_subFolders)) { return count($this->subFolders); } - $queryStr = "SELECT count(*) as c FROM tblFolders WHERE parent = " . $this->_id; + $queryStr = "SELECT count(*) as c FROM `tblFolders` WHERE `parent` = " . $this->_id; $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && !$resArr) return false; @@ -466,11 +466,11 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object { $db = $this->_dms->getDB(); if (!isset($this->_subFolders)) { - $queryStr = "SELECT * FROM tblFolders WHERE parent = " . $this->_id; + $queryStr = "SELECT * FROM `tblFolders` WHERE `parent` = " . $this->_id; - if ($orderby=="n") $queryStr .= " ORDER BY name"; - elseif ($orderby=="s") $queryStr .= " ORDER BY sequence"; - elseif ($orderby=="d") $queryStr .= " ORDER BY date"; + if ($orderby=="n") $queryStr .= " ORDER BY `name`"; + elseif ($orderby=="s") $queryStr .= " ORDER BY `sequence`"; + elseif ($orderby=="d") $queryStr .= " ORDER BY `date`"; if($dir == 'desc') $queryStr .= " DESC"; @@ -514,7 +514,7 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object { $db->startTransaction(); //inheritAccess = true, defaultAccess = M_READ - $queryStr = "INSERT INTO tblFolders (name, parent, folderList, comment, date, owner, inheritAccess, defaultAccess, sequence) ". + $queryStr = "INSERT INTO `tblFolders` (`name`, `parent`, `folderList`, `comment`, `date`, `owner`, `inheritAccess`, `defaultAccess`, `sequence`) ". "VALUES (".$db->qstr($name).", ".$this->_id.", ".$db->qstr($pathPrefix).", ".$db->qstr($comment).", ".$db->getCurrentTimestamp().", ".$owner->getID().", 1, ".M_READ.", ". $sequence.")"; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); @@ -618,7 +618,7 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object { if (isset($this->_documents)) { return count($this->documents); } - $queryStr = "SELECT count(*) as c FROM tblDocuments WHERE folder = " . $this->_id; + $queryStr = "SELECT count(*) as c FROM `tblDocuments` WHERE `folder` = " . $this->_id; $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && !$resArr) return false; @@ -637,7 +637,7 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object { if (isset($this->_documents)) { return count($this->documents); } - $queryStr = "SELECT count(*) as c FROM tblDocuments WHERE folder = " . $this->_id . " AND `name` = ".$db->qstr($name); + $queryStr = "SELECT count(*) as c FROM `tblDocuments` WHERE `folder` = " . $this->_id . " AND `name` = ".$db->qstr($name); $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && !$resArr) return false; @@ -660,10 +660,10 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object { $db = $this->_dms->getDB(); if (!isset($this->_documents)) { - $queryStr = "SELECT * FROM tblDocuments WHERE folder = " . $this->_id; - if ($orderby=="n") $queryStr .= " ORDER BY name"; - elseif($orderby=="s") $queryStr .= " ORDER BY sequence"; - elseif($orderby=="d") $queryStr .= " ORDER BY date"; + $queryStr = "SELECT * FROM `tblDocuments` WHERE `folder` = " . $this->_id; + if ($orderby=="n") $queryStr .= " ORDER BY `name`"; + elseif($orderby=="s") $queryStr .= " ORDER BY `sequence`"; + elseif($orderby=="d") $queryStr .= " ORDER BY `date`"; if($dir == 'desc') $queryStr .= " DESC"; @@ -715,7 +715,7 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object { $pathPrefix .= ":"; } - $queryStr = "SELECT id FROM tblFolders WHERE folderList like '".$pathPrefix. "%'"; + $queryStr = "SELECT id FROM `tblFolders` WHERE `folderList` like '".$pathPrefix. "%'"; $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && !$resArr) return false; @@ -745,7 +745,7 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object { $documents = array(); if($folderids) { - $queryStr = "SELECT id FROM tblDocuments WHERE folder in (".implode(',', $folderids). ")"; + $queryStr = "SELECT id FROM `tblDocuments` WHERE `folder` in (".implode(',', $folderids). ")"; $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && !$resArr) return false; @@ -818,7 +818,7 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object { $db->startTransaction(); - $queryStr = "INSERT INTO tblDocuments (name, comment, date, expires, owner, folder, folderList, inheritAccess, defaultAccess, locked, keywords, sequence) VALUES ". + $queryStr = "INSERT INTO `tblDocuments` (`name`, `comment`, `date`, `expires`, `owner`, `folder`, `folderList`, `inheritAccess`, `defaultAccess`, `locked`, `keywords`, `sequence`) VALUES ". "(".$db->qstr($name).", ".$db->qstr($comment).", ".$db->getCurrentTimestamp().", ".(int) $expires.", ".$owner->getID().", ".$this->_id.",".$db->qstr($pathPrefix).", 1, ".M_READ.", -1, ".$db->qstr($keywords).", " . $sequence . ")"; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); @@ -888,30 +888,30 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object { $db->startTransaction(); // unset homefolder as it will no longer exist - $queryStr = "UPDATE tblUsers SET homefolder=NULL WHERE homefolder = " . $this->_id; + $queryStr = "UPDATE `tblUsers` SET `homefolder`=NULL WHERE `homefolder` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } // Remove database entries - $queryStr = "DELETE FROM tblFolders WHERE id = " . $this->_id; + $queryStr = "DELETE FROM `tblFolders` WHERE `id` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } - $queryStr = "DELETE FROM tblFolderAttributes WHERE folder = " . $this->_id; + $queryStr = "DELETE FROM `tblFolderAttributes` WHERE `folder` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } - $queryStr = "DELETE FROM tblACLs WHERE target = ". $this->_id. " AND targetType = " . T_FOLDER; + $queryStr = "DELETE FROM `tblACLs` WHERE `target` = ". $this->_id. " AND `targetType` = " . T_FOLDER; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } - $queryStr = "DELETE FROM tblNotify WHERE target = ". $this->_id. " AND targetType = " . T_FOLDER; + $queryStr = "DELETE FROM `tblNotify` WHERE `target` = ". $this->_id. " AND `targetType` = " . T_FOLDER; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; @@ -1002,8 +1002,8 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object { if ($mode!=M_ANY) { $modeStr = " AND mode".$op.(int)$mode; } - $queryStr = "SELECT * FROM tblACLs WHERE targetType = ".T_FOLDER. - " AND target = " . $this->_id . $modeStr . " ORDER BY targetType"; + $queryStr = "SELECT * FROM `tblACLs` WHERE `targetType` = ".T_FOLDER. + " AND `target` = " . $this->_id . $modeStr . " ORDER BY `targetType`"; $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && !$resArr) return false; @@ -1029,7 +1029,7 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object { function clearAccessList($noclean=false) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "DELETE FROM tblACLs WHERE targetType = " . T_FOLDER . " AND target = " . $this->_id; + $queryStr = "DELETE FROM `tblACLs` WHERE `targetType` = " . T_FOLDER . " AND `target` = " . $this->_id; if (!$db->getResult($queryStr)) return false; @@ -1054,9 +1054,9 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object { function addAccess($mode, $userOrGroupID, $isUser) { /* {{{ */ $db = $this->_dms->getDB(); - $userOrGroup = ($isUser) ? "userID" : "groupID"; + $userOrGroup = ($isUser) ? "`userID`" : "`groupID`"; - $queryStr = "INSERT INTO tblACLs (target, targetType, ".$userOrGroup.", mode) VALUES + $queryStr = "INSERT INTO `tblACLs` (`target`, `targetType`, ".$userOrGroup.", `mode`) VALUES (".$this->_id.", ".T_FOLDER.", " . (int) $userOrGroupID . ", " .(int) $mode. ")"; if (!$db->getResult($queryStr)) return false; @@ -1084,9 +1084,9 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object { function changeAccess($newMode, $userOrGroupID, $isUser) { /* {{{ */ $db = $this->_dms->getDB(); - $userOrGroup = ($isUser) ? "userID" : "groupID"; + $userOrGroup = ($isUser) ? "`userID`" : "`groupID`"; - $queryStr = "UPDATE tblACLs SET mode = " . (int) $newMode . " WHERE targetType = ".T_FOLDER." AND target = " . $this->_id . " AND " . $userOrGroup . " = " . (int) $userOrGroupID; + $queryStr = "UPDATE `tblACLs` SET `mode` = " . (int) $newMode . " WHERE `targetType` = ".T_FOLDER." AND `target` = " . $this->_id . " AND " . $userOrGroup . " = " . (int) $userOrGroupID; if (!$db->getResult($queryStr)) return false; @@ -1103,9 +1103,9 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object { function removeAccess($userOrGroupID, $isUser) { /* {{{ */ $db = $this->_dms->getDB(); - $userOrGroup = ($isUser) ? "userID" : "groupID"; + $userOrGroup = ($isUser) ? "`userID`" : "`groupID`"; - $queryStr = "DELETE FROM tblACLs WHERE targetType = ".T_FOLDER." AND target = ".$this->_id." AND ".$userOrGroup." = " . (int) $userOrGroupID; + $queryStr = "DELETE FROM `tblACLs` WHERE `targetType` = ".T_FOLDER." AND `target` = ".$this->_id." AND ".$userOrGroup." = " . (int) $userOrGroupID; if (!$db->getResult($queryStr)) return false; @@ -1235,7 +1235,7 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object { if (empty($this->_notifyList)) { $db = $this->_dms->getDB(); - $queryStr ="SELECT * FROM tblNotify WHERE targetType = " . T_FOLDER . " AND target = " . $this->_id; + $queryStr ="SELECT * FROM `tblNotify` WHERE `targetType` = " . T_FOLDER . " AND `target` = " . $this->_id; $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && $resArr == false) return false; @@ -1297,7 +1297,7 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object { function addNotify($userOrGroupID, $isUser) { /* {{{ */ $db = $this->_dms->getDB(); - $userOrGroup = ($isUser) ? "userID" : "groupID"; + $userOrGroup = ($isUser) ? "`userID`" : "`groupID`"; /* Verify that user / group exists */ $obj = ($isUser ? $this->_dms->getUser($userOrGroupID) : $this->_dms->getGroup($userOrGroupID)); @@ -1383,7 +1383,7 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object { // $queryStr = "SELECT * FROM `tblNotify` WHERE `tblNotify`.`target` = '".$this->_id."' ". "AND `tblNotify`.`targetType` = '".T_FOLDER."' ". - "AND `tblNotify`.`".$userOrGroup."` = '". (int) $userOrGroupID."'"; + "AND `tblNotify`.".$userOrGroup." = '". (int) $userOrGroupID."'"; $resArr = $db->getResultArray($queryStr); if (is_bool($resArr)) { return -4; @@ -1392,7 +1392,7 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object { return -3; } - $queryStr = "INSERT INTO tblNotify (target, targetType, " . $userOrGroup . ") VALUES (" . $this->_id . ", " . T_FOLDER . ", " . (int) $userOrGroupID . ")"; + $queryStr = "INSERT INTO `tblNotify` (`target`, `targetType`, " . $userOrGroup . ") VALUES (" . $this->_id . ", " . T_FOLDER . ", " . (int) $userOrGroupID . ")"; if (!$db->getResult($queryStr)) return -4; @@ -1424,7 +1424,7 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object { return -1; } - $userOrGroup = ($isUser) ? "userID" : "groupID"; + $userOrGroup = ($isUser) ? "`userID`" : "`groupID`"; /* Verify that the requesting user has permission to add the target to * the notification system. @@ -1457,7 +1457,7 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object { // $queryStr = "SELECT * FROM `tblNotify` WHERE `tblNotify`.`target` = '".$this->_id."' ". "AND `tblNotify`.`targetType` = '".T_FOLDER."' ". - "AND `tblNotify`.`".$userOrGroup."` = '". (int) $userOrGroupID."'"; + "AND `tblNotify`.".$userOrGroup." = '". (int) $userOrGroupID."'"; $resArr = $db->getResultArray($queryStr); if (is_bool($resArr)) { return -4; @@ -1466,7 +1466,7 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object { return -3; } - $queryStr = "DELETE FROM tblNotify WHERE target = " . $this->_id . " AND targetType = " . T_FOLDER . " AND " . $userOrGroup . " = " . (int) $userOrGroupID; + $queryStr = "DELETE FROM `tblNotify` WHERE `target` = " . $this->_id . " AND `targetType` = " . T_FOLDER . " AND " . $userOrGroup . " = " . (int) $userOrGroupID; /* If type is given then delete only those notifications */ if($type) $queryStr .= " AND `type` = ".(int) $type; @@ -1627,7 +1627,7 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object { function getFolderList() { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "SELECT folderList FROM tblFolders where id = ".$this->_id; + $queryStr = "SELECT `folderList` FROM `tblFolders` where `id` = ".$this->_id; $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && !$resArr) return false; @@ -1656,7 +1656,7 @@ class SeedDMS_Core_Folder extends SeedDMS_Core_Object { $pathPrefix .= ":"; } if($curfolderlist != $pathPrefix) { - $queryStr = "UPDATE tblFolders SET folderList='".$pathPrefix."' WHERE id = ". $this->_id; + $queryStr = "UPDATE `tblFolders` SET `folderList`='".$pathPrefix."' WHERE `id` = ". $this->_id; $res = $db->getResult($queryStr); if (!$res) return false; diff --git a/SeedDMS_Core/Core/inc.ClassGroup.php b/SeedDMS_Core/Core/inc.ClassGroup.php index 954bf1f7e..7f7ab18f9 100644 --- a/SeedDMS_Core/Core/inc.ClassGroup.php +++ b/SeedDMS_Core/Core/inc.ClassGroup.php @@ -75,7 +75,7 @@ class SeedDMS_Core_Group { /* {{{ */ $queryStr = "SELECT * FROM `tblGroups` WHERE `name` = ".$db->qstr($id); break; default: - $queryStr = "SELECT * FROM `tblGroups` WHERE id = " . (int) $id; + $queryStr = "SELECT * FROM `tblGroups` WHERE `id` = " . (int) $id; } $resArr = $db->getResultArray($queryStr); @@ -96,7 +96,7 @@ class SeedDMS_Core_Group { /* {{{ */ switch($orderby) { default: - $queryStr = "SELECT * FROM tblGroups ORDER BY name"; + $queryStr = "SELECT * FROM `tblGroups` ORDER BY `name`"; } $resArr = $db->getResultArray($queryStr); @@ -124,7 +124,7 @@ class SeedDMS_Core_Group { /* {{{ */ function setName($newName) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblGroups SET name = ".$db->qstr($newName)." WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblGroups` SET `name` = ".$db->qstr($newName)." WHERE `id` = " . $this->_id; if (!$db->getResult($queryStr)) return false; @@ -137,7 +137,7 @@ class SeedDMS_Core_Group { /* {{{ */ function setComment($newComment) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblGroups SET comment = ".$db->qstr($newComment)." WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblGroups` SET `comment` = ".$db->qstr($newComment)." WHERE `id` = " . $this->_id; if (!$db->getResult($queryStr)) return false; @@ -172,7 +172,7 @@ class SeedDMS_Core_Group { /* {{{ */ $queryStr = "SELECT `tblUsers`.* FROM `tblUsers` ". "LEFT JOIN `tblGroupMembers` ON `tblGroupMembers`.`userID`=`tblUsers`.`id` ". - "WHERE `tblGroupMembers`.`groupID` = '". $this->_id ."' AND tblGroupMembers.manager = 1"; + "WHERE `tblGroupMembers`.`groupID` = '". $this->_id ."' AND `tblGroupMembers`.`manager` = 1"; $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && $resArr == false) return false; @@ -190,7 +190,7 @@ class SeedDMS_Core_Group { /* {{{ */ function addUser($user,$asManager=false) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "INSERT INTO tblGroupMembers (groupID, userID, manager) VALUES (".$this->_id.", ".$user->getID(). ", " . ($asManager?"1":"0") ." )"; + $queryStr = "INSERT INTO `tblGroupMembers` (`groupID`, `userID`, `manager`) VALUES (".$this->_id.", ".$user->getID(). ", " . ($asManager?"1":"0") ." )"; $res = $db->getResult($queryStr); if (!$res) return false; @@ -202,7 +202,7 @@ class SeedDMS_Core_Group { /* {{{ */ function removeUser($user) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "DELETE FROM tblGroupMembers WHERE groupID = ".$this->_id." AND userID = ".$user->getID(); + $queryStr = "DELETE FROM `tblGroupMembers` WHERE `groupID` = ".$this->_id." AND `userID` = ".$user->getID(); $res = $db->getResult($queryStr); if (!$res) return false; @@ -227,8 +227,8 @@ class SeedDMS_Core_Group { /* {{{ */ } $db = $this->_dms->getDB(); - if ($asManager) $queryStr = "SELECT * FROM tblGroupMembers WHERE groupID = " . $this->_id . " AND userID = " . $user->getID() . " AND manager = 1"; - else $queryStr = "SELECT * FROM tblGroupMembers WHERE groupID = " . $this->_id . " AND userID = " . $user->getID(); + if ($asManager) $queryStr = "SELECT * FROM `tblGroupMembers` WHERE `groupID` = " . $this->_id . " AND `userID` = " . $user->getID() . " AND `manager` = 1"; + else $queryStr = "SELECT * FROM `tblGroupMembers` WHERE `groupID` = " . $this->_id . " AND `userID` = " . $user->getID(); $resArr = $db->getResultArray($queryStr); @@ -249,8 +249,8 @@ class SeedDMS_Core_Group { /* {{{ */ if (!$this->isMember($user)) return false; - if ($this->isMember($user,true)) $queryStr = "UPDATE tblGroupMembers SET manager = 0 WHERE groupID = ".$this->_id." AND userID = ".$user->getID(); - else $queryStr = "UPDATE tblGroupMembers SET manager = 1 WHERE groupID = ".$this->_id." AND userID = ".$user->getID(); + if ($this->isMember($user,true)) $queryStr = "UPDATE `tblGroupMembers` SET `manager` = 0 WHERE `groupID` = ".$this->_id." AND `userID` = ".$user->getID(); + else $queryStr = "UPDATE `tblGroupMembers` SET `manager` = 1 WHERE `groupID` = ".$this->_id." AND `userID` = ".$user->getID(); if (!$db->getResult($queryStr)) return false; return true; @@ -270,37 +270,37 @@ class SeedDMS_Core_Group { /* {{{ */ $db->startTransaction(); - $queryStr = "DELETE FROM tblGroupMembers WHERE groupID = " . $this->_id; + $queryStr = "DELETE FROM `tblGroupMembers` WHERE `groupID` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } - $queryStr = "DELETE FROM tblACLs WHERE groupID = " . $this->_id; + $queryStr = "DELETE FROM `tblACLs` WHERE `groupID` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } - $queryStr = "DELETE FROM tblNotify WHERE groupID = " . $this->_id; + $queryStr = "DELETE FROM `tblNotify` WHERE `groupID` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } - $queryStr = "DELETE FROM tblMandatoryReviewers WHERE reviewerGroupID = " . $this->_id; + $queryStr = "DELETE FROM `tblMandatoryReviewers` WHERE `reviewerGroupID` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } - $queryStr = "DELETE FROM tblMandatoryApprovers WHERE approverGroupID = " . $this->_id; + $queryStr = "DELETE FROM `tblMandatoryApprovers` WHERE `approverGroupID` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } - $queryStr = "DELETE FROM tblWorkflowTransitionGroups WHERE groupid = " . $this->_id; + $queryStr = "DELETE FROM `tblWorkflowTransitionGroups` WHERE `groupid` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } - $queryStr = "DELETE FROM tblGroups WHERE id = " . $this->_id; + $queryStr = "DELETE FROM `tblGroups` WHERE `id` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; @@ -410,11 +410,11 @@ class SeedDMS_Core_Group { /* {{{ */ function getWorkflowStatus($documentID=null, $version=null) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = 'select distinct d.*, c.groupid from tblWorkflowTransitions a left join tblWorkflows b on a.workflow=b.id left join tblWorkflowTransitionGroups c on a.id=c.transition left join tblWorkflowDocumentContent d on b.id=d.workflow where d.document is not null and a.state=d.state and c.groupid='.$this->_id; + $queryStr = 'select distinct d.*, c.`groupid` from `tblWorkflowTransitions` a left join `tblWorkflows` b on a.`workflow`=b.`id` left join `tblWorkflowTransitionGroups` c on a.`id`=c.`transition` left join `tblWorkflowDocumentContent` d on b.`id`=d.`workflow` where d.`document` is not null and a.`state`=d.`state` and c.`groupid`='.$this->_id; if($documentID) { - $queryStr .= ' AND d.document='.(int) $documentID; + $queryStr .= ' AND d.`document`='.(int) $documentID; if($version) - $queryStr .= ' AND d.version='.(int) $version; + $queryStr .= ' AND d.`version`='.(int) $version; } $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && $resArr == false) diff --git a/SeedDMS_Core/Core/inc.ClassKeywords.php b/SeedDMS_Core/Core/inc.ClassKeywords.php index cf3bca2a5..0d58457be 100644 --- a/SeedDMS_Core/Core/inc.ClassKeywords.php +++ b/SeedDMS_Core/Core/inc.ClassKeywords.php @@ -71,7 +71,7 @@ class SeedDMS_Core_KeywordCategory { function setName($newName) { $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblKeywordCategories SET name = ".$db->qstr($newName)." WHERE id = ". $this->_id; + $queryStr = "UPDATE `tblKeywordCategories` SET `name` = ".$db->qstr($newName)." WHERE `id` = ". $this->_id; if (!$db->getResult($queryStr)) return false; @@ -82,7 +82,7 @@ class SeedDMS_Core_KeywordCategory { function setOwner($user) { $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblKeywordCategories SET owner = " . $user->getID() . " WHERE id " . $this->_id; + $queryStr = "UPDATE `tblKeywordCategories` SET `owner` = " . $user->getID() . " WHERE = `id` = " . $this->_id; if (!$db->getResult($queryStr)) return false; @@ -94,28 +94,28 @@ class SeedDMS_Core_KeywordCategory { function getKeywordLists() { $db = $this->_dms->getDB(); - $queryStr = "SELECT * FROM tblKeywords WHERE category = " . $this->_id . " order by `keywords`"; + $queryStr = "SELECT * FROM `tblKeywords` WHERE `category` = " . $this->_id . " order by `keywords`"; return $db->getResultArray($queryStr); } function editKeywordList($listID, $keywords) { $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblKeywords SET keywords = ".$db->qstr($keywords)." WHERE id = $listID"; + $queryStr = "UPDATE `tblKeywords` SET `keywords` = ".$db->qstr($keywords)." WHERE `id` = $listID"; return $db->getResult($queryStr); } function addKeywordList($keywords) { $db = $this->_dms->getDB(); - $queryStr = "INSERT INTO tblKeywords (category, keywords) VALUES (" . $this->_id . ", ".$db->qstr($keywords).")"; + $queryStr = "INSERT INTO `tblKeywords` (`category`, `keywords`) VALUES (" . $this->_id . ", ".$db->qstr($keywords).")"; return $db->getResult($queryStr); } function removeKeywordList($listID) { $db = $this->_dms->getDB(); - $queryStr = "DELETE FROM tblKeywords WHERE id = $listID"; + $queryStr = "DELETE FROM `tblKeywords` WHERE `id` = $listID"; return $db->getResult($queryStr); } @@ -123,13 +123,13 @@ class SeedDMS_Core_KeywordCategory { $db = $this->_dms->getDB(); $db->startTransaction(); - $queryStr = "DELETE FROM tblKeywords WHERE category = " . $this->_id; + $queryStr = "DELETE FROM `tblKeywords` WHERE `category` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } - $queryStr = "DELETE FROM tblKeywordCategories WHERE id = " . $this->_id; + $queryStr = "DELETE FROM `tblKeywordCategories` WHERE `id` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; diff --git a/SeedDMS_Core/Core/inc.ClassObject.php b/SeedDMS_Core/Core/inc.ClassObject.php index cff100589..e0cd1cbfb 100644 --- a/SeedDMS_Core/Core/inc.ClassObject.php +++ b/SeedDMS_Core/Core/inc.ClassObject.php @@ -75,13 +75,13 @@ class SeedDMS_Core_Object { /* {{{ */ switch(get_class($this)) { case $this->_dms->getClassname('document'): - $queryStr = "SELECT a.* FROM tblDocumentAttributes a LEFT JOIN tblAttributeDefinitions b ON a.attrdef=b.id WHERE a.document = " . $this->_id." ORDER BY b.`name`"; + $queryStr = "SELECT a.* FROM `tblDocumentAttributes` a LEFT JOIN `tblAttributeDefinitions` b ON a.`attrdef`=b.`id` WHERE a.`document` = " . $this->_id." ORDER BY b.`name`"; break; case $this->_dms->getClassname('documentcontent'): - $queryStr = "SELECT a.* FROM tblDocumentContentAttributes a LEFT JOIN tblAttributeDefinitions b ON a.attrdef=b.id WHERE a.content = " . $this->_id." ORDER BY b.`name`"; + $queryStr = "SELECT a.* FROM `tblDocumentContentAttributes` a LEFT JOIN `tblAttributeDefinitions` b ON a.`attrdef`=b.`id` WHERE a.`content` = " . $this->_id." ORDER BY b.`name`"; break; case $this->_dms->getClassname('folder'): - $queryStr = "SELECT a.* FROM tblFolderAttributes a LEFT JOIN tblAttributeDefinitions b ON a.attrdef=b.id WHERE a.folder = " . $this->_id." ORDER BY b.`name`"; + $queryStr = "SELECT a.* FROM `tblFolderAttributes` a LEFT JOIN `tblAttributeDefinitions` b ON a.`attrdef`=b.`id` WHERE a.`folder` = " . $this->_id." ORDER BY b.`name`"; break; default: return false; @@ -223,13 +223,13 @@ class SeedDMS_Core_Object { /* {{{ */ if(!isset($this->_attributes[$attrdef->getId()])) { switch(get_class($this)) { case $this->_dms->getClassname('document'): - $queryStr = "INSERT INTO tblDocumentAttributes (document, attrdef, value) VALUES (".$this->_id.", ".$attrdef->getId().", ".$db->qstr($value).")"; + $queryStr = "INSERT INTO `tblDocumentAttributes` (`document`, `attrdef`, `value`) VALUES (".$this->_id.", ".$attrdef->getId().", ".$db->qstr($value).")"; break; case $this->_dms->getClassname('documentcontent'): - $queryStr = "INSERT INTO tblDocumentContentAttributes (content, attrdef, value) VALUES (".$this->_id.", ".$attrdef->getId().", ".$db->qstr($value).")"; + $queryStr = "INSERT INTO `tblDocumentContentAttributes` (`content`, `attrdef`, `value`) VALUES (".$this->_id.", ".$attrdef->getId().", ".$db->qstr($value).")"; break; case $this->_dms->getClassname('folder'): - $queryStr = "INSERT INTO tblFolderAttributes (folder, attrdef, value) VALUES (".$this->_id.", ".$attrdef->getId().", ".$db->qstr($value).")"; + $queryStr = "INSERT INTO `tblFolderAttributes` (`folder`, `attrdef`, `value`) VALUES (".$this->_id.", ".$attrdef->getId().", ".$db->qstr($value).")"; break; default: return false; @@ -262,13 +262,13 @@ class SeedDMS_Core_Object { /* {{{ */ if(isset($this->_attributes[$attrdef->getId()])) { switch(get_class($this)) { case $this->_dms->getClassname('document'): - $queryStr = "DELETE FROM tblDocumentAttributes WHERE document=".$this->_id." AND attrdef=".$attrdef->getId(); + $queryStr = "DELETE FROM `tblDocumentAttributes` WHERE `document`=".$this->_id." AND `attrdef`=".$attrdef->getId(); break; case $this->_dms->getClassname('documentcontent'): - $queryStr = "DELETE FROM tblDocumentContentAttributes WHERE content=".$this->_id." AND attrdef=".$attrdef->getId(); + $queryStr = "DELETE FROM `tblDocumentContentAttributes` WHERE `content`=".$this->_id." AND `attrdef`=".$attrdef->getId(); break; case $this->_dms->getClassname('folder'): - $queryStr = "DELETE FROM tblFolderAttributes WHERE folder=".$this->_id." AND attrdef=".$attrdef->getId(); + $queryStr = "DELETE FROM `tblFolderAttributes` WHERE `folder`=".$this->_id." AND `attrdef`=".$attrdef->getId(); break; default: return false; diff --git a/SeedDMS_Core/Core/inc.ClassUser.php b/SeedDMS_Core/Core/inc.ClassUser.php index 19d530731..87e951d82 100644 --- a/SeedDMS_Core/Core/inc.ClassUser.php +++ b/SeedDMS_Core/Core/inc.ClassUser.php @@ -170,15 +170,15 @@ class SeedDMS_Core_User { /* {{{ */ switch($by) { case 'name': - $queryStr = "SELECT * FROM tblUsers WHERE login = ".$db->qstr($id); + $queryStr = "SELECT * FROM `tblUsers` WHERE `login` = ".$db->qstr($id); if($email) - $queryStr .= " AND email=".$db->qstr($email); + $queryStr .= " AND `email`=".$db->qstr($email); break; case 'email': - $queryStr = "SELECT * FROM tblUsers WHERE email = ".$db->qstr($id); + $queryStr = "SELECT * FROM `tblUsers` WHERE `email` = ".$db->qstr($id); break; default: - $queryStr = "SELECT * FROM tblUsers WHERE id = " . (int) $id; + $queryStr = "SELECT * FROM `tblUsers` WHERE `id` = " . (int) $id; } $resArr = $db->getResultArray($queryStr); @@ -196,9 +196,9 @@ class SeedDMS_Core_User { /* {{{ */ $db = $dms->getDB(); if($orderby == 'fullname') - $queryStr = "SELECT * FROM tblUsers ORDER BY fullname"; + $queryStr = "SELECT * FROM `tblUsers` ORDER BY `fullName`"; else - $queryStr = "SELECT * FROM tblUsers ORDER BY login"; + $queryStr = "SELECT * FROM `tblUsers` ORDER BY `login`"; $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && $resArr == false) @@ -226,7 +226,7 @@ class SeedDMS_Core_User { /* {{{ */ function setLogin($newLogin) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblUsers SET login =".$db->qstr($newLogin)." WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblUsers` SET `login` =".$db->qstr($newLogin)." WHERE `id` = " . $this->_id; $res = $db->getResult($queryStr); if (!$res) return false; @@ -240,7 +240,7 @@ class SeedDMS_Core_User { /* {{{ */ function setFullName($newFullName) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblUsers SET fullname = ".$db->qstr($newFullName)." WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblUsers` SET `fullName` = ".$db->qstr($newFullName)." WHERE `id` = " . $this->_id; $res = $db->getResult($queryStr); if (!$res) return false; @@ -254,7 +254,7 @@ class SeedDMS_Core_User { /* {{{ */ function setPwd($newPwd) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblUsers SET pwd =".$db->qstr($newPwd)." WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblUsers` SET `pwd` =".$db->qstr($newPwd)." WHERE `id` = " . $this->_id; $res = $db->getResult($queryStr); if (!$res) return false; @@ -268,9 +268,11 @@ class SeedDMS_Core_User { /* {{{ */ function setPwdExpiration($newPwdExpiration) { /* {{{ */ $db = $this->_dms->getDB(); - if(trim($newPwdExpiration) == '') + if(trim($newPwdExpiration) == '' || trim($newPwdExpiration) == 'never') $newPwdExpiration = '0000-00-00 00:00:00'; - $queryStr = "UPDATE tblUsers SET pwdExpiration =".$db->qstr($newPwdExpiration)." WHERE id = " . $this->_id; + elseif(trim($newPwdExpiration) == 'now') + $newPwdExpiration = date('Y-m-d H:i:s'); + $queryStr = "UPDATE `tblUsers` SET `pwdExpiration` =".$db->qstr($newPwdExpiration)." WHERE `id` = " . $this->_id; $res = $db->getResult($queryStr); if (!$res) return false; @@ -284,7 +286,7 @@ class SeedDMS_Core_User { /* {{{ */ function setEmail($newEmail) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblUsers SET email =".$db->qstr($newEmail)." WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblUsers` SET `email` =".$db->qstr($newEmail)." WHERE `id` = " . $this->_id; $res = $db->getResult($queryStr); if (!$res) return false; @@ -298,7 +300,7 @@ class SeedDMS_Core_User { /* {{{ */ function setLanguage($newLanguage) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblUsers SET language =".$db->qstr($newLanguage)." WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblUsers` SET `language` =".$db->qstr($newLanguage)." WHERE `id` = " . $this->_id; $res = $db->getResult($queryStr); if (!$res) return false; @@ -312,7 +314,7 @@ class SeedDMS_Core_User { /* {{{ */ function setTheme($newTheme) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblUsers SET theme =".$db->qstr($newTheme)." WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblUsers` SET `theme` =".$db->qstr($newTheme)." WHERE `id` = " . $this->_id; $res = $db->getResult($queryStr); if (!$res) return false; @@ -326,7 +328,7 @@ class SeedDMS_Core_User { /* {{{ */ function setComment($newComment) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblUsers SET comment =".$db->qstr($newComment)." WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblUsers` SET `comment` =".$db->qstr($newComment)." WHERE `id` = " . $this->_id; $res = $db->getResult($queryStr); if (!$res) return false; @@ -340,7 +342,7 @@ class SeedDMS_Core_User { /* {{{ */ function setRole($newrole) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblUsers SET role = " . $newrole . " WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblUsers` SET `role` = " . $newrole . " WHERE `id` = " . $this->_id; if (!$db->getResult($queryStr)) return false; @@ -353,7 +355,7 @@ class SeedDMS_Core_User { /* {{{ */ function setAdmin($isAdmin) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblUsers SET role = " . SeedDMS_Core_User::role_admin . " WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblUsers` SET `role` = " . SeedDMS_Core_User::role_admin . " WHERE `id` = " . $this->_id; if (!$db->getResult($queryStr)) return false; @@ -366,7 +368,7 @@ class SeedDMS_Core_User { /* {{{ */ function setGuest($isGuest) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblUsers SET role = " . SeedDMS_Core_User::role_guest . " WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblUsers` SET `role` = " . SeedDMS_Core_User::role_guest . " WHERE `id` = " . $this->_id; if (!$db->getResult($queryStr)) return false; @@ -380,7 +382,7 @@ class SeedDMS_Core_User { /* {{{ */ $db = $this->_dms->getDB(); $isHidden = ($isHidden) ? "1" : "0"; - $queryStr = "UPDATE tblUsers SET hidden = " . $isHidden . " WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblUsers` SET `hidden` = " . $isHidden . " WHERE `id` = " . $this->_id; if (!$db->getResult($queryStr)) return false; @@ -394,7 +396,7 @@ class SeedDMS_Core_User { /* {{{ */ $db = $this->_dms->getDB(); $isDisabled = ($isDisabled) ? "1" : "0"; - $queryStr = "UPDATE tblUsers SET disabled = " . $isDisabled . " WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblUsers` SET `disabled` = " . $isDisabled . " WHERE `id` = " . $this->_id; if (!$db->getResult($queryStr)) return false; @@ -406,7 +408,7 @@ class SeedDMS_Core_User { /* {{{ */ $db = $this->_dms->getDB(); $this->_loginFailures++; - $queryStr = "UPDATE tblUsers SET loginfailures = " . $this->_loginFailures . " WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblUsers` SET `loginfailures` = " . $this->_loginFailures . " WHERE `id` = " . $this->_id; if (!$db->getResult($queryStr)) return false; @@ -417,7 +419,7 @@ class SeedDMS_Core_User { /* {{{ */ $db = $this->_dms->getDB(); $this->_loginFailures = 0; - $queryStr = "UPDATE tblUsers SET loginfailures = " . $this->_loginFailures . " WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblUsers` SET `loginfailures` = " . $this->_loginFailures . " WHERE `id` = " . $this->_id; if (!$db->getResult($queryStr)) return false; @@ -435,7 +437,7 @@ class SeedDMS_Core_User { /* {{{ */ function getUsedDiskSpace() { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "SELECT SUM(filesize) sum FROM tblDocumentContent a LEFT JOIN tblDocuments b ON a.document=b.id WHERE b.owner = " . $this->_id; + $queryStr = "SELECT SUM(`fileSize`) sum FROM `tblDocumentContent` a LEFT JOIN `tblDocuments` b ON a.`document`=b.`id` WHERE b.`owner` = " . $this->_id; $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && $resArr == false) return false; @@ -449,7 +451,7 @@ class SeedDMS_Core_User { /* {{{ */ $db = $this->_dms->getDB(); $quota = intval($quota); - $queryStr = "UPDATE tblUsers SET quota = " . $quota . " WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblUsers` SET `quota` = " . $quota . " WHERE `id` = " . $this->_id; if (!$db->getResult($queryStr)) return false; @@ -462,7 +464,7 @@ class SeedDMS_Core_User { /* {{{ */ function setHomeFolder($homefolder) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblUsers SET homefolder = " . ($homefolder ? (int) $homefolder : NULL) . " WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblUsers` SET `homefolder` = " . ($homefolder ? (int) $homefolder : NULL) . " WHERE `id` = " . $this->_id; if (!$db->getResult($queryStr)) return false; @@ -496,10 +498,10 @@ class SeedDMS_Core_User { /* {{{ */ $db->startTransaction(); // delete private keyword lists - $queryStr = "SELECT tblKeywords.id FROM tblKeywords, tblKeywordCategories WHERE tblKeywords.category = tblKeywordCategories.id AND tblKeywordCategories.owner = " . $this->_id; + $queryStr = "SELECT `tblKeywords`.`id` FROM `tblKeywords`, `tblKeywordCategories` WHERE `tblKeywords`.`category` = `tblKeywordCategories`.`id` AND `tblKeywordCategories`.`owner` = " . $this->_id; $resultArr = $db->getResultArray($queryStr); if (count($resultArr) > 0) { - $queryStr = "DELETE FROM tblKeywords WHERE "; + $queryStr = "DELETE FROM `tblKeywords` WHERE "; for ($i = 0; $i < count($resultArr); $i++) { $queryStr .= "id = " . $resultArr[$i]["id"]; if ($i + 1 < count($resultArr)) @@ -511,155 +513,155 @@ class SeedDMS_Core_User { /* {{{ */ } } - $queryStr = "DELETE FROM tblKeywordCategories WHERE owner = " . $this->_id; + $queryStr = "DELETE FROM `tblKeywordCategories` WHERE `owner` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } //Benachrichtigungen entfernen - $queryStr = "DELETE FROM tblNotify WHERE userID = " . $this->_id; + $queryStr = "DELETE FROM `tblNotify` WHERE `userID` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } /* Assign documents of the removed user to the given user */ - $queryStr = "UPDATE tblFolders SET owner = " . $assignTo . " WHERE owner = " . $this->_id; + $queryStr = "UPDATE `tblFolders` SET `owner` = " . $assignTo . " WHERE `owner` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } - $queryStr = "UPDATE tblDocuments SET owner = " . $assignTo . " WHERE owner = " . $this->_id; + $queryStr = "UPDATE `tblDocuments` SET `owner` = " . $assignTo . " WHERE `owner` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } - $queryStr = "UPDATE tblDocumentContent SET createdBy = " . $assignTo . " WHERE createdBy = " . $this->_id; + $queryStr = "UPDATE `tblDocumentContent` SET `createdBy` = " . $assignTo . " WHERE `createdBy` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } // Remove private links on documents ... - $queryStr = "DELETE FROM tblDocumentLinks WHERE userID = " . $this->_id . " AND public = 0"; + $queryStr = "DELETE FROM `tblDocumentLinks` WHERE `userID` = " . $this->_id . " AND `public` = 0"; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } // ... but keep public links - $queryStr = "UPDATE tblDocumentLinks SET userID = " . $assignTo . " WHERE userID = " . $this->_id; + $queryStr = "UPDATE `tblDocumentLinks` SET `userID` = " . $assignTo . " WHERE `userID` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } // set administrator for deleted user's attachments - $queryStr = "UPDATE tblDocumentFiles SET userID = " . $assignTo . " WHERE userID = " . $this->_id; + $queryStr = "UPDATE `tblDocumentFiles` SET `userID` = " . $assignTo . " WHERE `userID` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } // unlock documents locked by the user - $queryStr = "DELETE FROM tblDocumentLocks WHERE userID = " . $this->_id; + $queryStr = "DELETE FROM `tblDocumentLocks` WHERE `userID` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } // Delete user from all groups - $queryStr = "DELETE FROM tblGroupMembers WHERE userID = " . $this->_id; + $queryStr = "DELETE FROM `tblGroupMembers` WHERE `userID` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } // User aus allen ACLs streichen - $queryStr = "DELETE FROM tblACLs WHERE userID = " . $this->_id; + $queryStr = "DELETE FROM `tblACLs` WHERE `userID` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } // Delete image of user - $queryStr = "DELETE FROM tblUserImages WHERE userID = " . $this->_id; + $queryStr = "DELETE FROM `tblUserImages` WHERE `userID` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } // Delete entries in password history - $queryStr = "DELETE FROM tblUserPasswordHistory WHERE userID = " . $this->_id; + $queryStr = "DELETE FROM `tblUserPasswordHistory` WHERE `userID` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } // Delete entries in password request - $queryStr = "DELETE FROM tblUserPasswordRequest WHERE userID = " . $this->_id; + $queryStr = "DELETE FROM `tblUserPasswordRequest` WHERE `userID` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } // mandatory review/approve - $queryStr = "DELETE FROM tblMandatoryReviewers WHERE reviewerUserID = " . $this->_id; + $queryStr = "DELETE FROM `tblMandatoryReviewers` WHERE `reviewerUserID` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } - $queryStr = "DELETE FROM tblMandatoryApprovers WHERE approverUserID = " . $this->_id; + $queryStr = "DELETE FROM `tblMandatoryApprovers` WHERE `approverUserID` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } - $queryStr = "DELETE FROM tblMandatoryReviewers WHERE userID = " . $this->_id; + $queryStr = "DELETE FROM `tblMandatoryReviewers` WHERE `userID` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } - $queryStr = "DELETE FROM tblMandatoryApprovers WHERE userID = " . $this->_id; + $queryStr = "DELETE FROM `tblMandatoryApprovers` WHERE `userID` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } - $queryStr = "DELETE FROM tblWorkflowMandatoryWorkflow WHERE userid = " . $this->_id; + $queryStr = "DELETE FROM `tblWorkflowMandatoryWorkflow` WHERE `userid` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } - $queryStr = "DELETE FROM tblWorkflowTransitionUsers WHERE userid = " . $this->_id; + $queryStr = "DELETE FROM `tblWorkflowTransitionUsers` WHERE `userid` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } // set administrator for deleted user's events - $queryStr = "UPDATE tblEvents SET userID = " . $assignTo . " WHERE userID = " . $this->_id; + $queryStr = "UPDATE `tblEvents` SET `userID` = " . $assignTo . " WHERE `userID` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } // Delete user itself - $queryStr = "DELETE FROM tblUsers WHERE id = " . $this->_id; + $queryStr = "DELETE FROM `tblUsers` WHERE `id` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } // TODO : update document status if reviewer/approver has been deleted - // "DELETE FROM tblDocumentApproveLog WHERE userID = " . $this->_id; - // "DELETE FROM tblDocumentReviewLog WHERE userID = " . $this->_id; + // "DELETE FROM `tblDocumentApproveLog` WHERE `userID` = " . $this->_id; + // "DELETE FROM `tblDocumentReviewLog` WHERE `userID` = " . $this->_id; $reviewStatus = $this->getReviewStatus(); @@ -775,7 +777,7 @@ class SeedDMS_Core_User { /* {{{ */ if (!isset($this->_hasImage)) { $db = $this->_dms->getDB(); - $queryStr = "SELECT COUNT(*) AS num FROM tblUserImages WHERE userID = " . $this->_id; + $queryStr = "SELECT COUNT(*) AS num FROM `tblUserImages` WHERE `userID` = " . $this->_id; $resArr = $db->getResultArray($queryStr); if ($resArr === false) return false; @@ -795,7 +797,7 @@ class SeedDMS_Core_User { /* {{{ */ function getImage() { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "SELECT * FROM tblUserImages WHERE userID = " . $this->_id; + $queryStr = "SELECT * FROM `tblUserImages` WHERE `userID` = " . $this->_id; $resArr = $db->getResultArray($queryStr); if ($resArr === false) return false; @@ -814,9 +816,9 @@ class SeedDMS_Core_User { /* {{{ */ fclose($fp); if ($this->hasImage()) - $queryStr = "UPDATE tblUserImages SET image = '".base64_encode($content)."', mimeType = ".$db->qstr($mimeType)." WHERE userID = " . $this->_id; + $queryStr = "UPDATE `tblUserImages` SET `image` = '".base64_encode($content)."', `mimeType` = ".$db->qstr($mimeType)." WHERE `userID` = " . $this->_id; else - $queryStr = "INSERT INTO tblUserImages (userID, image, mimeType) VALUES (" . $this->_id . ", '".base64_encode($content)."', ".$db->qstr($mimeType).")"; + $queryStr = "INSERT INTO `tblUserImages` (`userID`, `image`, `mimeType`) VALUES (" . $this->_id . ", '".base64_encode($content)."', ".$db->qstr($mimeType).")"; if (!$db->getResult($queryStr)) return false; @@ -1059,11 +1061,11 @@ class SeedDMS_Core_User { /* {{{ */ function getWorkflowStatus($documentID=null, $version=null) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = 'SELECT DISTINCT d.*, c.userid FROM tblWorkflowTransitions a LEFT JOIN tblWorkflows b ON a.workflow=b.id LEFT JOIN tblWorkflowTransitionUsers c ON a.id=c.transition LEFT JOIN tblWorkflowDocumentContent d ON b.id=d.workflow WHERE d.document IS NOT NULL AND a.state=d.state AND c.userid='.$this->_id; + $queryStr = 'SELECT DISTINCT d.*, c.`userid` FROM `tblWorkflowTransitions` a LEFT JOIN `tblWorkflows` b ON a.`workflow`=b.`id` LEFT JOIN `tblWorkflowTransitionUsers` c ON a.`id`=c.`transition` LEFT JOIN `tblWorkflowDocumentContent` d ON b.`id`=d.`workflow` WHERE d.`document` IS NOT NULL AND a.`state`=d.`state` AND c.`userid`='.$this->_id; if($documentID) { - $queryStr .= ' AND d.document='.(int) $documentID; + $queryStr .= ' AND d.`document`='.(int) $documentID; if($version) - $queryStr .= ' AND d.version='.(int) $version; + $queryStr .= ' AND d.`version`='.(int) $version; } $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && $resArr == false) @@ -1075,11 +1077,11 @@ class SeedDMS_Core_User { /* {{{ */ } } - $queryStr = 'select distinct d.*, c.groupid from tblWorkflowTransitions a left join tblWorkflows b on a.workflow=b.id left join tblWorkflowTransitionGroups c on a.id=c.transition left join tblWorkflowDocumentContent d on b.id=d.workflow left join tblGroupMembers e on c.groupid = e.groupID where d.document is not null and a.state=d.state and e.userID='.$this->_id; + $queryStr = 'select distinct d.*, c.`groupid` from `tblWorkflowTransitions` a left join `tblWorkflows` b on a.`workflow`=b.`id` left join `tblWorkflowTransitionGroups` c on a.`id`=c.`transition` left join `tblWorkflowDocumentContent` d on b.`id`=d.`workflow` left join `tblGroupMembers` e on c.`groupid` = e.`groupID` where d.`document` is not null and a.`state`=d.`state` and e.`userID`='.$this->_id; if($documentID) { - $queryStr .= ' AND d.document='.(int) $documentID; + $queryStr .= ' AND d.`document`='.(int) $documentID; if($version) - $queryStr .= ' AND d.version='.(int) $version; + $queryStr .= ' AND d.`version`='.(int) $version; } $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && $resArr == false) @@ -1106,7 +1108,7 @@ class SeedDMS_Core_User { /* {{{ */ function getMandatoryReviewers() { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "SELECT * FROM tblMandatoryReviewers WHERE userID = " . $this->_id; + $queryStr = "SELECT * FROM `tblMandatoryReviewers` WHERE `userID` = " . $this->_id; $resArr = $db->getResultArray($queryStr); return $resArr; @@ -1122,7 +1124,7 @@ class SeedDMS_Core_User { /* {{{ */ function getMandatoryApprovers() { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "SELECT * FROM tblMandatoryApprovers WHERE userID = " . $this->_id; + $queryStr = "SELECT * FROM `tblMandatoryApprovers` WHERE `userID` = " . $this->_id; $resArr = $db->getResultArray($queryStr); return $resArr; @@ -1140,7 +1142,7 @@ class SeedDMS_Core_User { /* {{{ */ function getMandatoryWorkflow() { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "SELECT * FROM tblWorkflowMandatoryWorkflow WHERE userid = " . $this->_id; + $queryStr = "SELECT * FROM `tblWorkflowMandatoryWorkflow` WHERE `userid` = " . $this->_id; $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && !$resArr) return false; @@ -1163,7 +1165,7 @@ class SeedDMS_Core_User { /* {{{ */ function getMandatoryWorkflows() { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "SELECT * FROM tblWorkflowMandatoryWorkflow WHERE userid = " . $this->_id; + $queryStr = "SELECT * FROM `tblWorkflowMandatoryWorkflow` WHERE `userid` = " . $this->_id; $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && !$resArr) return false; @@ -1190,21 +1192,21 @@ class SeedDMS_Core_User { /* {{{ */ if ($isgroup){ - $queryStr = "SELECT * FROM tblMandatoryReviewers WHERE userID = " . $this->_id . " AND reviewerGroupID = " . $id; + $queryStr = "SELECT * FROM `tblMandatoryReviewers` WHERE `userID` = " . $this->_id . " AND `reviewerGroupID` = " . $id; $resArr = $db->getResultArray($queryStr); if (count($resArr)!=0) return true; - $queryStr = "INSERT INTO tblMandatoryReviewers (userID, reviewerGroupID) VALUES (" . $this->_id . ", " . $id .")"; + $queryStr = "INSERT INTO `tblMandatoryReviewers` (`userID`, `reviewerGroupID`) VALUES (" . $this->_id . ", " . $id .")"; $resArr = $db->getResult($queryStr); if (is_bool($resArr) && !$resArr) return false; }else{ - $queryStr = "SELECT * FROM tblMandatoryReviewers WHERE userID = " . $this->_id . " AND reviewerUserID = " . $id; + $queryStr = "SELECT * FROM `tblMandatoryReviewers` WHERE `userID` = " . $this->_id . " AND `reviewerUserID` = " . $id; $resArr = $db->getResultArray($queryStr); if (count($resArr)!=0) return true; - $queryStr = "INSERT INTO tblMandatoryReviewers (userID, reviewerUserID) VALUES (" . $this->_id . ", " . $id .")"; + $queryStr = "INSERT INTO `tblMandatoryReviewers` (`userID`, `reviewerUserID`) VALUES (" . $this->_id . ", " . $id .")"; $resArr = $db->getResult($queryStr); if (is_bool($resArr) && !$resArr) return false; } @@ -1224,21 +1226,21 @@ class SeedDMS_Core_User { /* {{{ */ if ($isgroup){ - $queryStr = "SELECT * FROM tblMandatoryApprovers WHERE userID = " . $this->_id . " AND approverGroupID = " . (int) $id; + $queryStr = "SELECT * FROM `tblMandatoryApprovers` WHERE `userID` = " . $this->_id . " AND `approverGroupID` = " . (int) $id; $resArr = $db->getResultArray($queryStr); if (count($resArr)!=0) return; - $queryStr = "INSERT INTO tblMandatoryApprovers (userID, approverGroupID) VALUES (" . $this->_id . ", " . $id .")"; + $queryStr = "INSERT INTO `tblMandatoryApprovers` (`userID`, `approverGroupID`) VALUES (" . $this->_id . ", " . $id .")"; $resArr = $db->getResult($queryStr); if (is_bool($resArr) && !$resArr) return false; }else{ - $queryStr = "SELECT * FROM tblMandatoryApprovers WHERE userID = " . $this->_id . " AND approverUserID = " . (int) $id; + $queryStr = "SELECT * FROM `tblMandatoryApprovers` WHERE `userID` = " . $this->_id . " AND `approverUserID` = " . (int) $id; $resArr = $db->getResultArray($queryStr); if (count($resArr)!=0) return; - $queryStr = "INSERT INTO tblMandatoryApprovers (userID, approverUserID) VALUES (" . $this->_id . ", " . $id .")"; + $queryStr = "INSERT INTO `tblMandatoryApprovers` (`userID`, `approverUserID`) VALUES (" . $this->_id . ", " . $id .")"; $resArr = $db->getResult($queryStr); if (is_bool($resArr) && !$resArr) return false; } @@ -1254,11 +1256,11 @@ class SeedDMS_Core_User { /* {{{ */ function setMandatoryWorkflow($workflow) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "SELECT * FROM tblWorkflowMandatoryWorkflow WHERE userid = " . $this->_id . " AND workflow = " . (int) $workflow->getID(); + $queryStr = "SELECT * FROM `tblWorkflowMandatoryWorkflow` WHERE `userid` = " . $this->_id . " AND `workflow` = " . (int) $workflow->getID(); $resArr = $db->getResultArray($queryStr); if (count($resArr)!=0) return; - $queryStr = "INSERT INTO tblWorkflowMandatoryWorkflow (userid, workflow) VALUES (" . $this->_id . ", " . $workflow->getID() .")"; + $queryStr = "INSERT INTO `tblWorkflowMandatoryWorkflow` (`userid`, `workflow`) VALUES (" . $this->_id . ", " . $workflow->getID() .")"; $resArr = $db->getResult($queryStr); if (is_bool($resArr) && !$resArr) return false; } /* }}} */ @@ -1274,14 +1276,14 @@ class SeedDMS_Core_User { /* {{{ */ $db = $this->_dms->getDB(); $db->startTransaction(); - $queryStr = "DELETE FROM tblWorkflowMandatoryWorkflow WHERE userid = " . $this->_id; + $queryStr = "DELETE FROM `tblWorkflowMandatoryWorkflow` WHERE `userid` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } foreach($workflows as $workflow) { - $queryStr = "INSERT INTO tblWorkflowMandatoryWorkflow (userid, workflow) VALUES (" . $this->_id . ", " . $workflow->getID() .")"; + $queryStr = "INSERT INTO `tblWorkflowMandatoryWorkflow` (`userid`, `workflow`) VALUES (" . $this->_id . ", " . $workflow->getID() .")"; $resArr = $db->getResult($queryStr); if (is_bool($resArr) && !$resArr) { $db->rollbackTransaction(); @@ -1300,7 +1302,7 @@ class SeedDMS_Core_User { /* {{{ */ */ function delMandatoryReviewers() { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "DELETE FROM tblMandatoryReviewers WHERE userID = " . $this->_id; + $queryStr = "DELETE FROM `tblMandatoryReviewers` WHERE `userID` = " . $this->_id; if (!$db->getResult($queryStr)) return false; return true; } /* }}} */ @@ -1313,7 +1315,7 @@ class SeedDMS_Core_User { /* {{{ */ function delMandatoryApprovers() { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "DELETE FROM tblMandatoryApprovers WHERE userID = " . $this->_id; + $queryStr = "DELETE FROM `tblMandatoryApprovers` WHERE `userID` = " . $this->_id; if (!$db->getResult($queryStr)) return false; return true; } /* }}} */ @@ -1325,7 +1327,7 @@ class SeedDMS_Core_User { /* {{{ */ */ function delMandatoryWorkflow() { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "DELETE FROM tblWorkflowMandatoryWorkflow WHERE userid = " . $this->_id; + $queryStr = "DELETE FROM `tblWorkflowMandatoryWorkflow` WHERE `userid` = " . $this->_id; if (!$db->getResult($queryStr)) return false; return true; } /* }}} */ diff --git a/SeedDMS_Core/Core/inc.ClassWorkflow.php b/SeedDMS_Core/Core/inc.ClassWorkflow.php index f3c491c86..579098427 100644 --- a/SeedDMS_Core/Core/inc.ClassWorkflow.php +++ b/SeedDMS_Core/Core/inc.ClassWorkflow.php @@ -75,7 +75,7 @@ class SeedDMS_Core_Workflow { /* {{{ */ function setName($newName) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblWorkflows SET name = ".$db->qstr($newName)." WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblWorkflows` SET `name` = ".$db->qstr($newName)." WHERE `id` = " . $this->_id; $res = $db->getResult($queryStr); if (!$res) return false; @@ -89,7 +89,7 @@ class SeedDMS_Core_Workflow { /* {{{ */ function setInitState($state) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblWorkflows SET initstate = ".$state->getID()." WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblWorkflows` SET `initstate` = ".$state->getID()." WHERE `id` = " . $this->_id; $res = $db->getResult($queryStr); if (!$res) return false; @@ -104,7 +104,7 @@ class SeedDMS_Core_Workflow { /* {{{ */ if($this->_transitions) return $this->_transitions; - $queryStr = "SELECT * FROM tblWorkflowTransitions WHERE workflow=".$this->_id; + $queryStr = "SELECT * FROM `tblWorkflowTransitions` WHERE `workflow`=".$this->_id; $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && $resArr == false) return false; @@ -165,7 +165,7 @@ class SeedDMS_Core_Workflow { /* {{{ */ function getNextTransitions($state) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "SELECT * FROM tblWorkflowTransitions WHERE workflow=".$this->_id." AND state=".$state->getID(); + $queryStr = "SELECT * FROM `tblWorkflowTransitions` WHERE `workflow`=".$this->_id." AND `state`=".$state->getID(); $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && $resArr == false) return false; @@ -189,7 +189,7 @@ class SeedDMS_Core_Workflow { /* {{{ */ function getPreviousTransitions($state) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "SELECT * FROM tblWorkflowTransitions WHERE workflow=".$this->_id." AND nextstate=".$state->getID(); + $queryStr = "SELECT * FROM `tblWorkflowTransitions` WHERE `workflow`=".$this->_id." AND `nextstate`=".$state->getID(); $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && $resArr == false) return false; @@ -214,7 +214,7 @@ class SeedDMS_Core_Workflow { /* {{{ */ function getTransitionsByStates($state, $nextstate) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "SELECT * FROM tblWorkflowTransitions WHERE workflow=".$this->_id." AND state=".$state->getID()." AND nextstate=".$nextstate->getID(); + $queryStr = "SELECT * FROM `tblWorkflowTransitions` WHERE `workflow`=".$this->_id." AND `state`=".$state->getID()." AND `nextstate`=".$nextstate->getID(); $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && $resArr == false) return false; @@ -254,7 +254,7 @@ class SeedDMS_Core_Workflow { /* {{{ */ $db = $this->_dms->getDB(); $db->startTransaction(); - $queryStr = "INSERT INTO tblWorkflowTransitions (workflow, state, action, nextstate) VALUES (".$this->_id.", ".$state->getID().", ".$action->getID().", ".$nextstate->getID().")"; + $queryStr = "INSERT INTO `tblWorkflowTransitions` (`workflow`, `state`, `action`, `nextstate`) VALUES (".$this->_id.", ".$state->getID().", ".$action->getID().", ".$nextstate->getID().")"; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; @@ -267,7 +267,7 @@ class SeedDMS_Core_Workflow { /* {{{ */ $transition = $this->getTransition($db->getInsertID()); foreach($users as $user) { - $queryStr = "INSERT INTO tblWorkflowTransitionUsers (transition, userid) VALUES (".$transition->getID().", ".$user->getID().")"; + $queryStr = "INSERT INTO `tblWorkflowTransitionUsers` (`transition`, `userid`) VALUES (".$transition->getID().", ".$user->getID().")"; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; @@ -275,7 +275,7 @@ class SeedDMS_Core_Workflow { /* {{{ */ } foreach($groups as $group) { - $queryStr = "INSERT INTO tblWorkflowTransitionGroups (transition, groupid, minusers) VALUES (".$transition->getID().", ".$group->getID().", 1)"; + $queryStr = "INSERT INTO `tblWorkflowTransitionGroups` (`transition`, `groupid`, `minusers`) VALUES (".$transition->getID().", ".$group->getID().", 1)"; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; @@ -294,7 +294,7 @@ class SeedDMS_Core_Workflow { /* {{{ */ function isUsed() { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "SELECT * FROM tblWorkflowDocumentContent WHERE workflow=".$this->_id; + $queryStr = "SELECT * FROM `tblWorkflowDocumentContent` WHERE `workflow`=".$this->_id; $resArr = $db->getResultArray($queryStr); if (is_array($resArr) && count($resArr) == 0) return false; @@ -345,20 +345,20 @@ class SeedDMS_Core_Workflow { /* {{{ */ $db->startTransaction(); - $queryStr = "DELETE FROM tblWorkflowTransitions WHERE workflow = " . $this->_id; + $queryStr = "DELETE FROM `tblWorkflowTransitions` WHERE `workflow` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } - $queryStr = "DELETE FROM tblWorkflowMandatoryWorkflow WHERE workflow = " . $this->_id; + $queryStr = "DELETE FROM `tblWorkflowMandatoryWorkflow` WHERE `workflow` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } // Delete workflow itself - $queryStr = "DELETE FROM tblWorkflows WHERE id = " . $this->_id; + $queryStr = "DELETE FROM `tblWorkflows` WHERE `id` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; @@ -443,7 +443,7 @@ class SeedDMS_Core_Workflow_State { /* {{{ */ function setName($newName) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblWorkflowStates SET name = ".$db->qstr($newName)." WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblWorkflowStates` SET `name` = ".$db->qstr($newName)." WHERE `id` = " . $this->_id; $res = $db->getResult($queryStr); if (!$res) return false; @@ -457,7 +457,7 @@ class SeedDMS_Core_Workflow_State { /* {{{ */ function setMaxTime($maxtime) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblWorkflowStates SET maxtime = ".intval($maxtime)." WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblWorkflowStates` SET `maxtime` = ".intval($maxtime)." WHERE `id` = " . $this->_id; $res = $db->getResult($queryStr); if (!$res) return false; @@ -471,7 +471,7 @@ class SeedDMS_Core_Workflow_State { /* {{{ */ function setPreCondFunc($precondfunc) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblWorkflowStates SET precondfunc = ".$db->qstr($precondfunc)." WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblWorkflowStates` SET `precondfunc` = ".$db->qstr($precondfunc)." WHERE id = " . $this->_id; $res = $db->getResult($queryStr); if (!$res) return false; @@ -493,7 +493,7 @@ class SeedDMS_Core_Workflow_State { /* {{{ */ function setDocumentStatus($docstatus) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblWorkflowStates SET documentstatus = ".intval($docstatus)." WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblWorkflowStates` SET `documentstatus` = ".intval($docstatus)." WHERE id = " . $this->_id; $res = $db->getResult($queryStr); if (!$res) return false; @@ -510,7 +510,7 @@ class SeedDMS_Core_Workflow_State { /* {{{ */ function isUsed() { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "SELECT * FROM tblWorkflowTransitions WHERE state=".$this->_id. " OR nextstate=".$this->_id; + $queryStr = "SELECT * FROM `tblWorkflowTransitions` WHERE `state`=".$this->_id. " OR `nextstate`=".$this->_id; $resArr = $db->getResultArray($queryStr); if (is_array($resArr) && count($resArr) == 0) return false; @@ -525,7 +525,7 @@ class SeedDMS_Core_Workflow_State { /* {{{ */ function getTransitions() { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "SELECT * FROM tblWorkflowTransitions WHERE state=".$this->_id. " OR nextstate=".$this->_id; + $queryStr = "SELECT * FROM `tblWorkflowTransitions` WHERE `state`=".$this->_id. " OR `nextstate`=".$this->_id; $resArr = $db->getResultArray($queryStr); if (is_array($resArr) && count($resArr) == 0) return false; @@ -555,7 +555,7 @@ class SeedDMS_Core_Workflow_State { /* {{{ */ $db->startTransaction(); // Delete workflow state itself - $queryStr = "DELETE FROM tblWorkflowStates WHERE id = " . $this->_id; + $queryStr = "DELETE FROM `tblWorkflowStates` WHERE `id` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; @@ -616,7 +616,7 @@ class SeedDMS_Core_Workflow_Action { /* {{{ */ function setName($newName) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblWorkflowActions SET name = ".$db->qstr($newName)." WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblWorkflowActions` SET `name` = ".$db->qstr($newName)." WHERE `id` = " . $this->_id; $res = $db->getResult($queryStr); if (!$res) return false; @@ -633,7 +633,7 @@ class SeedDMS_Core_Workflow_Action { /* {{{ */ function isUsed() { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "SELECT * FROM tblWorkflowTransitions WHERE action=".$this->_id; + $queryStr = "SELECT * FROM `tblWorkflowTransitions` WHERE `action`=".$this->_id; $resArr = $db->getResultArray($queryStr); if (is_array($resArr) && count($resArr) == 0) return false; @@ -648,7 +648,7 @@ class SeedDMS_Core_Workflow_Action { /* {{{ */ function getTransitions() { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "SELECT * FROM tblWorkflowTransitions WHERE action=".$this->_id; + $queryStr = "SELECT * FROM `tblWorkflowTransitions` WHERE `action`=".$this->_id; $resArr = $db->getResultArray($queryStr); if (is_array($resArr) && count($resArr) == 0) return false; @@ -678,7 +678,7 @@ class SeedDMS_Core_Workflow_Action { /* {{{ */ $db->startTransaction(); // Delete workflow state itself - $queryStr = "DELETE FROM tblWorkflowActions WHERE id = " . $this->_id; + $queryStr = "DELETE FROM `tblWorkflowActions` WHERE `id` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; @@ -785,7 +785,7 @@ class SeedDMS_Core_Workflow_Transition { /* {{{ */ function setWorkflow($newWorkflow) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblWorkflowTransitions SET workflow = ".$newWorkflow->getID()." WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblWorkflowTransitions` SET `workflow` = ".$newWorkflow->getID()." WHERE `id` = " . $this->_id; $res = $db->getResult($queryStr); if (!$res) return false; @@ -799,7 +799,7 @@ class SeedDMS_Core_Workflow_Transition { /* {{{ */ function setState($newState) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblWorkflowTransitions SET state = ".$newState->getID()." WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblWorkflowTransitions` SET `state` = ".$newState->getID()." WHERE `id` = " . $this->_id; $res = $db->getResult($queryStr); if (!$res) return false; @@ -813,7 +813,7 @@ class SeedDMS_Core_Workflow_Transition { /* {{{ */ function setNextState($newNextState) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblWorkflowTransitions SET nextstate = ".$newNextState->getID()." WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblWorkflowTransitions` SET `nextstate` = ".$newNextState->getID()." WHERE `id` = " . $this->_id; $res = $db->getResult($queryStr); if (!$res) return false; @@ -827,7 +827,7 @@ class SeedDMS_Core_Workflow_Transition { /* {{{ */ function setAction($newAction) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblWorkflowTransitions SET action = ".$newAction->getID()." WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblWorkflowTransitions` SET `action` = ".$newAction->getID()." WHERE `id` = " . $this->_id; $res = $db->getResult($queryStr); if (!$res) return false; @@ -841,7 +841,7 @@ class SeedDMS_Core_Workflow_Transition { /* {{{ */ function setMaxTime($maxtime) { /* {{{ */ $db = $this->_dms->getDB(); - $queryStr = "UPDATE tblWorkflowTransitions SET maxtime = ".intval($maxtime)." WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblWorkflowTransitions` SET `maxtime` = ".intval($maxtime)." WHERE `id` = " . $this->_id; $res = $db->getResult($queryStr); if (!$res) return false; @@ -861,7 +861,7 @@ class SeedDMS_Core_Workflow_Transition { /* {{{ */ if($this->_users) return $this->_users; - $queryStr = "SELECT * FROM tblWorkflowTransitionUsers WHERE transition=".$this->_id; + $queryStr = "SELECT * FROM `tblWorkflowTransitionUsers` WHERE `transition`=".$this->_id; $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && $resArr == false) return false; @@ -889,7 +889,7 @@ class SeedDMS_Core_Workflow_Transition { /* {{{ */ if($this->_groups) return $this->_groups; - $queryStr = "SELECT * FROM tblWorkflowTransitionGroups WHERE transition=".$this->_id; + $queryStr = "SELECT * FROM `tblWorkflowTransitionGroups` WHERE `transition`=".$this->_id; $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && $resArr == false) return false; @@ -918,7 +918,7 @@ class SeedDMS_Core_Workflow_Transition { /* {{{ */ $db->startTransaction(); // Delete workflow transition itself - $queryStr = "DELETE FROM tblWorkflowTransitions WHERE id = " . $this->_id; + $queryStr = "DELETE FROM `tblWorkflowTransitions` WHERE `id` = " . $this->_id; if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; diff --git a/SeedDMS_Core/Core/inc.DBAccessPDO.php b/SeedDMS_Core/Core/inc.DBAccessPDO.php index 4bd77a0d8..f59355cd3 100644 --- a/SeedDMS_Core/Core/inc.DBAccessPDO.php +++ b/SeedDMS_Core/Core/inc.DBAccessPDO.php @@ -213,6 +213,16 @@ class SeedDMS_Core_DatabaseAccess { return $this->_conn->quote($text); } /* }}} */ + /** + * Replace back ticks by '"' + * + * @param string text + * @return string sanitized string + */ + function rbt($text) { /* {{{ */ + return str_replace('`', '"'); + } /* }}} */ + /** * Execute SQL query and return result * @@ -402,7 +412,7 @@ class SeedDMS_Core_DatabaseAccess { else if (!strcasecmp($tableName, "ttcontentid")) { switch($this->_driver) { case 'sqlite': - $queryStr = "CREATE TEMPORARY TABLE `ttcontentid` AS ". + $queryStr = "CREATE TEMPORARY TABLE IF NOT EXISTS `ttcontentid` AS ". "SELECT `tblDocumentContent`.`document` AS `document`, ". "MAX(`tblDocumentContent`.`version`) AS `maxVersion` ". "FROM `tblDocumentContent` ". @@ -410,7 +420,7 @@ class SeedDMS_Core_DatabaseAccess { "ORDER BY `tblDocumentContent`.`document`"; break; default: - $queryStr = "CREATE TEMPORARY TABLE `ttcontentid` (PRIMARY KEY (`document`), INDEX (`maxVersion`)) ". + $queryStr = "CREATE TEMPORARY TABLE IF NOT EXISTS `ttcontentid` (PRIMARY KEY (`document`), INDEX (`maxVersion`)) ". "SELECT `tblDocumentContent`.`document`, ". "MAX(`tblDocumentContent`.`version`) AS `maxVersion` ". "FROM `tblDocumentContent` ". diff --git a/SeedDMS_Core/package.xml b/SeedDMS_Core/package.xml index 6bc09f684..ebff746a9 100644 --- a/SeedDMS_Core/package.xml +++ b/SeedDMS_Core/package.xml @@ -12,11 +12,11 @@ uwe@steinmann.cx yes - 2016-11-02 + 2017-02-20 - 5.0.9 - 5.0.9 + 5.0.10 + 5.0.10 stable @@ -24,7 +24,7 @@ GPL License -- all changes from 4.3.32 merged +- all changes from 4.3.33 merged @@ -1147,6 +1147,25 @@ SeedDMS_Core_DMS::getNotificationsByUser() are deprecated - SeedDMS_Core_DMS::search() can search for document/folder id + + 2017-02-22 + + + 4.3.33 + 4.3.33 + + + stable + stable + + GPL License + +- SeedDMЅ_Core_DMS::getTimeline() no longer returns duplicate documents +- SeedDMЅ_Core_Document::addContent() sets workflow after status was set +- SeedDMЅ_Core_Keyword::setOwner() fix sql statement +- SeedDMЅ_Core_User::setFullname() minor fix in sql statement + + 2016-01-22 @@ -1161,7 +1180,7 @@ SeedDMS_Core_DMS::getNotificationsByUser() are deprecated GPL License - all changes from 4.3.24 merged - + 2016-04-26 @@ -1277,5 +1296,21 @@ SeedDMS_Core_DMS::getNotificationsByUser() are deprecated - all changes from 4.3.31 merged + + 2016-11-02 + + + 5.0.9 + 5.0.9 + + + stable + stable + + GPL License + +- all changes from 4.3.32 merged + + diff --git a/README.Extensions b/doc/README.Extensions similarity index 99% rename from README.Extensions rename to doc/README.Extensions index d1654f7dd..11038e857 100644 --- a/README.Extensions +++ b/doc/README.Extensions @@ -1,5 +1,5 @@ Extensions in SeedDMS -==================== +===================== Since verson 5.0.0 SeedDMS can be extended by extensions. Extensions can hook up functions into certain operations, e.g. diff --git a/doc/README.Hooks b/doc/README.Hooks new file mode 100644 index 000000000..5e171ed4e --- /dev/null +++ b/doc/README.Hooks @@ -0,0 +1,85 @@ +Hooks +====== + +Attention: the api for hooks isn't stable yet! + +Hooks in SeedDMS are user definied methods which are being called by +the application. The SeedDMS Core also has hooks which are being +called from the core itself. They are not subject of this document. +The SeedDMS application distinguishes between + +* view hooks and +* controller hooks + +view hooks usually return some html output which is send to the browser +and either replaces the default output or adds additional information. +A view hooks which returns false will be considered as not being called +at all. + +controller hooks implement additional functions which either replace +existing functions or add new ones. If such a hook returns null then +this is treated as if the hook was not called. If the hook returns +false it will prevent other hooks implementing the same function from +being called. All other return values will not stop other hooks from +being called. + +Currently available controller hooks +------------------------------------ +AddDocument::preAddDocument + Called before a new document will be added + +AddDocument::postAddDocument + Called after a new document has been added + +AddDocument::preIndexDocument + Called before a new document will be indexed + +UpdateDocument::preUpdateDocument + Called before a new document will be updated + +UpdateDocument::postUpdateDocument + Called after a new document has been updated + +UpdateDocument::preIndexDocument + Called before an updated document will be indexed + +RemoveDocument::preRemoveDocument + Called before a document will be removed + +RemoveDocument::removeDocument + Called for removing the document. If the hook returns null the + regular document removal will happen. + +RemoveDocument::postRemoveDocument + Called after a document was removed + +RemoveFolder::preRemoveFolder + Called before a document will be removed + +RemoveFolder::removeFolder + Called for removing the folder. If the hook returns null the + regular folder removal will happen. + +RemoveFolder::postRemoveFolder + Called after a document was removed + +EditFolder::preEditFolder + +EditFolder::EditFolder + +EditFolder::postEditFolder + +ViewOnline::version + Called when a document is downloaded for online view + +Download::version + Called when a document is downloaded for saving on disk + +Login::postLogin + Called after user in fully logged in + +Logout::postLogout + Called after user is logged out + +Currently available view hooks +------------------------------------ diff --git a/doc/README.Notification b/doc/README.Notification index 8ec3dffd5..c00664cee 100644 --- a/doc/README.Notification +++ b/doc/README.Notification @@ -108,7 +108,6 @@ op/op.TriggerWorkflow.php * Workflow transition was triggered subscribers of the document -op/op.UpdateDocument2.php op/op.UpdateDocument.php * document was updated subscribers of the document diff --git a/doc/README.Translation b/doc/README.Translation new file mode 100644 index 000000000..8ca6fe141 --- /dev/null +++ b/doc/README.Translation @@ -0,0 +1,42 @@ +Help translating SeedDMS +=========================== + +SeedDMS has got many translations over the years and it is a major +task to keep them all updated. If you would like to give a helping +hand, then this will be much appreciated. There are various ways +to contribute translations. + +1. The demo version of SeedDMS at https://demo.seeddms.org will list +all missing translations in a formular on the bottom of the page +while using the software. You can easily provide a missing translation +by filling out the form and submitting it. The translation will not +instantly be used, but is taken over into the official version of +SeedDMS once in a while. This method does not allow to submit corrected +translations of existing phrases. + +2. Fixing translations is only possible by modifying one of the language +files in `lanuages/xx_XX/lang.inc`. These files are php files containing +one large array named `$text`. Any modification will be visible right away +in your SeedDMS installation. If you intend to pass your modifications to +the developers of SeedDMS, than keep your changes seperate from the +original translation. A good way is to put your changes into a new +file, e.g. `lang-local.inc` containing an array named `$text_local` and +merge that array with the original translation array. Just put at the +end of `lanuages/xx_XX/lang.inc` the follwing code: + + include('lang-local.inc'); + array_merge($text, $text_local); + +Also create the file `lang-local.inc` with the content + + 'yyy', + ); + ?> + +Once you are ready with your local modifications and you think those are +good enough for the public version of SeedDMS, then please mail them to +info@seeddms.org + + diff --git a/inc/inc.Calendar.php b/inc/inc.Calendar.php deleted file mode 100644 index 9ce19ae07..000000000 --- a/inc/inc.Calendar.php +++ /dev/null @@ -1,95 +0,0 @@ -= " . $date; - $ret = $db->getResultArray($queryStr); - return $ret; -} - -function getEventsInInterval($start, $stop){ - - global $db; - - $queryStr = "SELECT * FROM tblEvents WHERE ( start <= " . (int) $start . " AND stop >= " . (int) $start . " ) ". - "OR ( start <= " . (int) $stop . " AND stop >= " . (int) $stop . " ) ". - "OR ( start >= " . (int) $start . " AND stop <= " . (int) $stop . " )"; - $ret = $db->getResultArray($queryStr); - return $ret; -} - -function addEvent($from, $to, $name, $comment ){ - - global $db,$user; - - $queryStr = "INSERT INTO tblEvents (name, comment, start, stop, date, userID) VALUES ". - "(".$db->qstr($name).", ".$db->qstr($comment).", ".(int) $from.", ".(int) $to.", ".$db->getCurrentTimestamp().", ".$user->getID().")"; - - $ret = $db->getResult($queryStr); - return $ret; -} - -function getEvent($id){ - - if (!is_numeric($id)) return false; - - global $db; - - $queryStr = "SELECT * FROM tblEvents WHERE id = " . (int) $id; - $ret = $db->getResultArray($queryStr); - - if (is_bool($ret) && $ret == false) return false; - else if (count($ret) != 1) return false; - - return $ret[0]; -} - -function editEvent($id, $from, $to, $name, $comment ){ - - if (!is_numeric($id)) return false; - - global $db; - - $queryStr = "UPDATE tblEvents SET start = " . (int) $from . ", stop = " . (int) $to . ", name = " . $db->qstr($name) . ", comment = " . $db->qstr($comment) . ", date = " . $db->getCurrentTimestamp() . " WHERE id = ". (int) $id; - $ret = $db->getResult($queryStr); - return $ret; -} - -function delEvent($id){ - - if (!is_numeric($id)) return false; - - global $db; - - $queryStr = "DELETE FROM tblEvents WHERE id = " . (int) $id; - $ret = $db->getResult($queryStr); - return $ret; -} - -?> diff --git a/inc/inc.ClassCalendar.php b/inc/inc.ClassCalendar.php new file mode 100644 index 000000000..e50aafc7f --- /dev/null +++ b/inc/inc.ClassCalendar.php @@ -0,0 +1,93 @@ + + * @copyright Copyright (C) 2010 Matteo Lucarelli, + * 2017 Uwe Steinmann + * @version Release: @package_version@ + */ + +/** + * Include parent class + */ +require_once("inc.ClassNotify.php"); + +/** + * Class to manage events + * + * @category DMS + * @package SeedDMS + * @author Markus Westphal, Malcolm Cowe, Uwe Steinmann + * @copyright Copyright (C) 2010 Matteo Lucarelli, + * 2017 Uwe Steinmann + * @version Release: @package_version@ + */ +class SeedDMS_Calendar { + /** + * Instanz of database + */ + protected $db; + + function __construct($db, $user) { + $this->db = $db; + $this->user = $user; + } + + function getEvents($day, $month, $year) { /* {{{ */ + $date = mktime(12,0,0, $month, $day, $year); + + $queryStr = "SELECT * FROM `tblEvents` WHERE `start` <= " . $date . " AND `stop` >= " . $date; + $ret = $this->db->getResultArray($queryStr); + return $ret; + } /* }}} */ + + function getEventsInInterval($start, $stop) { /* {{{ */ + $queryStr = "SELECT * FROM `tblEvents` WHERE ( `start` <= " . (int) $start . " AND `stop` >= " . (int) $start . " ) ". + "OR ( `start` <= " . (int) $stop . " AND `stop` >= " . (int) $stop . " ) ". + "OR ( `start` >= " . (int) $start . " AND `stop` <= " . (int) $stop . " )"; + $ret = $this->db->getResultArray($queryStr); + return $ret; + } /* }}} */ + + function addEvent($from, $to, $name, $comment ) { /* {{{ */ + $queryStr = "INSERT INTO `tblEvents` (`name`, `comment`, `start`, `stop`, `date`, `userID`) VALUES ". + "(".$this->db->qstr($name).", ".$this->db->qstr($comment).", ".(int) $from.", ".(int) $to.", ".$this->db->getCurrentTimestamp().", ".$this->user->getID().")"; + + $ret = $this->db->getResult($queryStr); + return $ret; + } /* }}} */ + + function getEvent($id) { /* {{{ */ + if (!is_numeric($id)) return false; + + $queryStr = "SELECT * FROM `tblEvents` WHERE `id` = " . (int) $id; + $ret = $this->db->getResultArray($queryStr); + + if (is_bool($ret) && $ret == false) return false; + else if (count($ret) != 1) return false; + + return $ret[0]; + } /* }}} */ + + function editEvent($id, $from, $to=null, $name=null, $comment=null) { /* {{{ */ + if (!is_numeric($id)) return false; + + $queryStr = "UPDATE `tblEvents` SET `start` = " . (int) $from . ($to !== null ? ", `stop` = " . (int) $to : '') . ($name !== null ? ", `name` = " . $this->db->qstr($name) : '') . ($comment !== null ? ", `comment` = " . $this->db->qstr($comment) : '') . ", `date` = " . $this->db->getCurrentTimestamp() . " WHERE `id` = ". (int) $id; + $ret = $this->db->getResult($queryStr); + return $ret; + } /* }}} */ + + function delEvent($id) { /* {{{ */ + if (!is_numeric($id)) return false; + + $queryStr = "DELETE FROM `tblEvents` WHERE `id` = " . (int) $id; + $ret = $this->db->getResult($queryStr); + return $ret; + } /* }}} */ +} +?> diff --git a/inc/inc.ClassPasswordHistoryManager.php b/inc/inc.ClassPasswordHistoryManager.php index 6c8b8f1f5..5855cfcee 100644 --- a/inc/inc.ClassPasswordHistoryManager.php +++ b/inc/inc.ClassPasswordHistoryManager.php @@ -47,7 +47,7 @@ class SeedDMS_PasswordHistoryManager { } /* }}} */ function add($user, $pwd) { /* {{{ */ - $queryStr = "INSERT INTO tblUserPasswordHistory (userID, pwd, `date`) ". + $queryStr = "INSERT INTO `tblUserPasswordHistory` (`userID`, `pwd`, `date`) ". "VALUES (".$this->db->qstr($user->getId()).", ".$this->db->qstr($pwd).", ".$this->db->getCurrentDatetime().")"; if (!$this->db->getResult($queryStr)) { return false; @@ -55,7 +55,7 @@ class SeedDMS_PasswordHistoryManager { } /* }}} */ function search($user, $pwd) { /* {{{ */ - $queryStr = "SELECT * FROM tblUserPasswordHistory WHERE userID = ".$this->db->qstr($user->getId())." AND pwd=".$this->db->qstr($pwd); + $queryStr = "SELECT * FROM `tblUserPasswordHistory` WHERE `userID` = ".$this->db->qstr($user->getId())." AND `pwd`=".$this->db->qstr($pwd); $resArr = $this->db->getResultArray($queryStr); if (is_bool($resArr) && $resArr == false) diff --git a/inc/inc.ClassSession.php b/inc/inc.ClassSession.php index d67532521..e6c7dd206 100644 --- a/inc/inc.ClassSession.php +++ b/inc/inc.ClassSession.php @@ -67,7 +67,7 @@ class SeedDMS_Session { * @return boolean true if successful otherwise false */ function load($id) { /* {{{ */ - $queryStr = "SELECT * FROM tblSessions WHERE id = ".$this->db->qstr($id); + $queryStr = "SELECT * FROM `tblSessions` WHERE `id` = ".$this->db->qstr($id); $resArr = $this->db->getResultArray($queryStr); if (is_bool($resArr) && $resArr == false) return false; @@ -97,7 +97,7 @@ class SeedDMS_Session { $id = "" . rand() . time() . rand() . ""; $id = md5($id); $lastaccess = time(); - $queryStr = "INSERT INTO tblSessions (id, userID, lastAccess, theme, language, su) ". + $queryStr = "INSERT INTO `tblSessions` (`id`, `userID`, `lastAccess`, `theme`, `language`, `su`) ". "VALUES ('".$id."', ".$data['userid'].", ".$lastaccess.", '".$data['theme']."', '".$data['lang']."', 0)"; if (!$this->db->getResult($queryStr)) { return false; @@ -126,7 +126,7 @@ class SeedDMS_Session { * @return boolean true if successful otherwise false */ function updateAccess($id) { /* {{{ */ - $queryStr = "UPDATE tblSessions SET lastAccess = " . time() . " WHERE id = " . $this->db->qstr($id); + $queryStr = "UPDATE `tblSessions` SET `lastAccess` = " . time() . " WHERE `id` = " . $this->db->qstr($id); if (!$this->db->getResult($queryStr)) return false; return true; @@ -139,7 +139,7 @@ class SeedDMS_Session { * @return boolean true if successful otherwise false */ function deleteByTime($sec) { /* {{{ */ - $queryStr = "DELETE FROM tblSessions WHERE " . time() . " - lastAccess > ".$sec; + $queryStr = "DELETE FROM `tblSessions` WHERE " . time() . " - `lastAccess` > ".$sec; if (!$this->db->getResult($queryStr)) { return false; } @@ -153,7 +153,7 @@ class SeedDMS_Session { * @return boolean true if successful otherwise false */ function delete($id) { /* {{{ */ - $queryStr = "DELETE FROM tblSessions WHERE id = " . $this->db->qstr($id); + $queryStr = "DELETE FROM `tblSessions` WHERE `id` = " . $this->db->qstr($id); if (!$this->db->getResult($queryStr)) { return false; } @@ -178,7 +178,7 @@ class SeedDMS_Session { function setUser($userid) { /* {{{ */ /* id is only set if load() was called before */ if($this->id) { - $queryStr = "UPDATE tblSessions SET userID = " . $this->db->qstr($userid) . " WHERE id = " . $this->db->qstr($this->id); + $queryStr = "UPDATE `tblSessions` SET `userID` = " . $this->db->qstr($userid) . " WHERE `id` = " . $this->db->qstr($this->id); if (!$this->db->getResult($queryStr)) return false; $this->data['userid'] = $userid; @@ -194,7 +194,7 @@ class SeedDMS_Session { function setLanguage($lang) { /* {{{ */ /* id is only set if load() was called before */ if($this->id) { - $queryStr = "UPDATE tblSessions SET language = " . $this->db->qstr($lang) . " WHERE id = " . $this->db->qstr($this->id); + $queryStr = "UPDATE `tblSessions` SET `language` = " . $this->db->qstr($lang) . " WHERE `id` = " . $this->db->qstr($this->id); if (!$this->db->getResult($queryStr)) return false; $this->data['lang'] = $lang; @@ -219,7 +219,7 @@ class SeedDMS_Session { function setSu($su) { /* {{{ */ /* id is only set if load() was called before */ if($this->id) { - $queryStr = "UPDATE tblSessions SET su = " . (int) $su . " WHERE id = " . $this->db->qstr($this->id); + $queryStr = "UPDATE `tblSessions` SET `su` = " . (int) $su . " WHERE `id` = " . $this->db->qstr($this->id); if (!$this->db->getResult($queryStr)) return false; $this->data['su'] = (int) $su; @@ -235,7 +235,7 @@ class SeedDMS_Session { function resetSu() { /* {{{ */ /* id is only set if load() was called before */ if($this->id) { - $queryStr = "UPDATE tblSessions SET su = 0 WHERE id = " . $this->db->qstr($this->id); + $queryStr = "UPDATE `tblSessions` SET `su` = 0 WHERE `id` = " . $this->db->qstr($this->id); if (!$this->db->getResult($queryStr)) return false; $this->data['su'] = 0; @@ -260,7 +260,7 @@ class SeedDMS_Session { function setClipboard($clipboard) { /* {{{ */ /* id is only set if load() was called before */ if($this->id) { - $queryStr = "UPDATE tblSessions SET clipboard = " . $this->db->qstr(json_encode($clipboard)) . " WHERE id = " . $this->db->qstr($this->id); + $queryStr = "UPDATE `tblSessions` SET `clipboard` = " . $this->db->qstr(json_encode($clipboard)) . " WHERE `id` = " . $this->db->qstr($this->id); if (!$this->db->getResult($queryStr)) return false; $this->data['clipboard'] = $clipboard; @@ -293,7 +293,7 @@ class SeedDMS_Session { if(!in_array($object->getID(), $this->data['clipboard']['folders'])) array_push($this->data['clipboard']['folders'], $object->getID()); } - $queryStr = "UPDATE tblSessions SET clipboard = " . $this->db->qstr(json_encode($this->data['clipboard'])) . " WHERE id = " . $this->db->qstr($this->id); + $queryStr = "UPDATE `tblSessions` SET `clipboard` = " . $this->db->qstr(json_encode($this->data['clipboard'])) . " WHERE `id` = " . $this->db->qstr($this->id); if (!$this->db->getResult($queryStr)) return false; } @@ -318,7 +318,7 @@ class SeedDMS_Session { if($key !== false) unset($this->data['clipboard']['folders'][$key]); } - $queryStr = "UPDATE tblSessions SET clipboard = " . $this->db->qstr(json_encode($this->data['clipboard'])) . " WHERE id = " . $this->db->qstr($this->id); + $queryStr = "UPDATE `tblSessions` SET `clipboard` = " . $this->db->qstr(json_encode($this->data['clipboard'])) . " WHERE `id` = " . $this->db->qstr($this->id); if (!$this->db->getResult($queryStr)) return false; } @@ -332,7 +332,7 @@ class SeedDMS_Session { function clearClipboard() { /* {{{ */ $this->data['clipboard']['docs'] = array(); $this->data['clipboard']['folders'] = array(); - $queryStr = "UPDATE tblSessions SET clipboard = " . $this->db->qstr(json_encode($this->data['clipboard'])) . " WHERE id = " . $this->db->qstr($this->id); + $queryStr = "UPDATE `tblSessions` SET `clipboard` = " . $this->db->qstr(json_encode($this->data['clipboard'])) . " WHERE `id` = " . $this->db->qstr($this->id); if (!$this->db->getResult($queryStr)) return false; return true; @@ -346,7 +346,7 @@ class SeedDMS_Session { function setSplashMsg($msg) { /* {{{ */ /* id is only set if load() was called before */ if($this->id) { - $queryStr = "UPDATE tblSessions SET splashmsg = " . $this->db->qstr(json_encode($msg)) . " WHERE id = " . $this->db->qstr($this->id); + $queryStr = "UPDATE `tblSessions` SET `splashmsg` = " . $this->db->qstr(json_encode($msg)) . " WHERE `id` = " . $this->db->qstr($this->id); if (!$this->db->getResult($queryStr)) return false; $this->data['splashmsg'] = $msg; @@ -362,7 +362,7 @@ class SeedDMS_Session { function clearSplashMsg() { /* {{{ */ /* id is only set if load() was called before */ if($this->id) { - $queryStr = "UPDATE tblSessions SET splashmsg = '' WHERE id = " . $this->db->qstr($this->id); + $queryStr = "UPDATE `tblSessions` SET `splashmsg` = '' WHERE `id` = " . $this->db->qstr($this->id); if (!$this->db->getResult($queryStr)) return false; $this->data['splashmsg'] = ''; @@ -430,7 +430,7 @@ class SeedDMS_SessionMgr { $id = "" . rand() . time() . rand() . ""; $id = md5($id); $lastaccess = time(); - $queryStr = "INSERT INTO tblSessions (id, userID, lastAccess, theme, language, su) ". + $queryStr = "INSERT INTO `tblSessions` (`id`, `userID`, `lastAccess`, `theme`, `language`, `su`) ". "VALUES ('".$id."', ".$data['userid'].", ".$lastaccess.", '".$data['theme']."', '".$data['lang']."', 0)"; if (!$this->db->getResult($queryStr)) { return false; @@ -445,7 +445,7 @@ class SeedDMS_SessionMgr { * @return array list of sessions */ function getAllSessions() { /* {{{ */ - $queryStr = "SELECT * FROM tblSessions"; + $queryStr = "SELECT * FROM `tblSessions`"; $resArr = $this->db->getResultArray($queryStr); if (is_bool($resArr) && $resArr == false) return false; @@ -465,7 +465,7 @@ class SeedDMS_SessionMgr { * @return array list of sessions */ function getUserSessions($user) { /* {{{ */ - $queryStr = "SELECT * FROM tblSessions WHERE userID=".$user->getID(); + $queryStr = "SELECT * FROM `tblSessions` WHERE `userID`=".$user->getID(); $resArr = $this->db->getResultArray($queryStr); if (is_bool($resArr) && $resArr == false) return false; diff --git a/inc/inc.ClassUI.php b/inc/inc.ClassUI.php index 557c1fd5b..7b786245e 100644 --- a/inc/inc.ClassUI.php +++ b/inc/inc.ClassUI.php @@ -56,16 +56,19 @@ class UI extends UI_Default { * to rootDir or an extension dir if it has set the include path */ $filename = ''; + $httpbasedir = ''; foreach($EXT_CONF as $extname=>$extconf) { if(!isset($extconf['disable']) || $extconf['disable'] == false) { $filename = $settings->_rootDir.'ext/'.$extname.'/views/'.$theme."/class.".$class.".php"; if(file_exists($filename)) { + $httpbasedir = 'ext/'.$extname.'/'; break; } $filename = ''; if(isset($extconf['views'][$class])) { $filename = $settings->_rootDir.'ext/'.$extname.'/views/'.$theme."/".$extconf['views'][$class]['file']; if(file_exists($filename)) { + $httpbasedir = 'ext/'.$extname.'/'; $classname = $extconf['views'][$class]['name']; break; } @@ -81,6 +84,7 @@ class UI extends UI_Default { $view = new $classname($params, $theme); /* Set some configuration parameters */ $view->setParam('refferer', $_SERVER['REQUEST_URI']); + $view->setParam('absbaseprefix', $settings->_httpRoot.$httpbasedir); $view->setParam('class', $class); $view->setParam('session', $session); $view->setParam('settings', $settings); diff --git a/inc/inc.Version.php b/inc/inc.Version.php index 4cc8a9dd1..a903ac52d 100644 --- a/inc/inc.Version.php +++ b/inc/inc.Version.php @@ -20,7 +20,7 @@ class SeedDMS_Version { - public $_number = "5.0.9"; + public $_number = "5.0.10"; private $_string = "SeedDMS"; function __construct() { diff --git a/install/create_tables-innodb.sql b/install/create_tables-innodb.sql index 9e6d8b41c..847118b28 100644 --- a/install/create_tables-innodb.sql +++ b/install/create_tables-innodb.sql @@ -1,292 +1,306 @@ --- +-- -- Table structure for table `tblACLs` --- +-- CREATE TABLE `tblACLs` ( - `id` int(11) NOT NULL auto_increment, - `target` int(11) NOT NULL default '0', - `targetType` tinyint(4) NOT NULL default '0', - `userID` int(11) NOT NULL default '-1', - `groupID` int(11) NOT NULL default '-1', - `mode` tinyint(4) NOT NULL default '0', - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - --- -------------------------------------------------------- - --- --- Table structure for table `tblCategory` --- - -CREATE TABLE `tblCategory` ( - `id` int(11) NOT NULL auto_increment, - `name` text NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - --- -------------------------------------------------------- - --- --- Table structure for table `tblAttributeDefinitions` --- - -CREATE TABLE `tblAttributeDefinitions` ( - `id` int(11) NOT NULL auto_increment, - `name` varchar(100) default NULL, - `objtype` tinyint(4) NOT NULL default '0', - `type` tinyint(4) NOT NULL default '0', - `multiple` tinyint(4) NOT NULL default '0', - `minvalues` int(11) NOT NULL default '0', - `maxvalues` int(11) NOT NULL default '0', - `valueset` text default NULL, - `regex` text default NULL, - UNIQUE(`name`), + `id` int(11) NOT NULL AUTO_INCREMENT, + `target` int(11) NOT NULL DEFAULT '0', + `targetType` tinyint(4) NOT NULL DEFAULT '0', + `userID` int(11) NOT NULL DEFAULT '-1', + `groupID` int(11) NOT NULL DEFAULT '-1', + `mode` tinyint(4) NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- --- --- Table structure for table `tblUsers` --- +-- +-- Table structure for table `tblCategory` +-- -CREATE TABLE `tblUsers` ( - `id` int(11) NOT NULL auto_increment, - `login` varchar(50) default NULL, - `pwd` varchar(50) default NULL, - `fullName` varchar(100) default NULL, - `email` varchar(70) default NULL, - `language` varchar(32) NOT NULL, - `theme` varchar(32) NOT NULL, - `comment` text NOT NULL, - `role` smallint(1) NOT NULL default '0', - `hidden` smallint(1) NOT NULL default '0', - `pwdExpiration` datetime NOT NULL default '0000-00-00 00:00:00', - `loginfailures` tinyint(4) NOT NULL default '0', - `disabled` smallint(1) NOT NULL default '0', - `quota` bigint, - `homefolder` int(11) default NULL, - PRIMARY KEY (`id`), - UNIQUE (`login`) +CREATE TABLE `tblCategory` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` text NOT NULL, + PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- --- +-- +-- Table structure for table `tblAttributeDefinitions` +-- + +CREATE TABLE `tblAttributeDefinitions` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(100) DEFAULT NULL, + `objtype` tinyint(4) NOT NULL DEFAULT '0', + `type` tinyint(4) NOT NULL DEFAULT '0', + `multiple` tinyint(4) NOT NULL DEFAULT '0', + `minvalues` int(11) NOT NULL DEFAULT '0', + `maxvalues` int(11) NOT NULL DEFAULT '0', + `valueset` text DEFAULT NULL, + `regex` text DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `name` (`name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `tblUsers` +-- + +CREATE TABLE `tblUsers` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `login` varchar(50) DEFAULT NULL, + `pwd` varchar(50) DEFAULT NULL, + `fullName` varchar(100) DEFAULT NULL, + `email` varchar(70) DEFAULT NULL, + `language` varchar(32) NOT NULL, + `theme` varchar(32) NOT NULL, + `comment` text NOT NULL, + `role` smallint(1) NOT NULL DEFAULT '0', + `hidden` smallint(1) NOT NULL DEFAULT '0', + `pwdExpiration` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `loginfailures` tinyint(4) NOT NULL DEFAULT '0', + `disabled` smallint(1) NOT NULL DEFAULT '0', + `quota` bigint(20) DEFAULT NULL, + `homefolder` int(11) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `login` (`login`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- -- Table structure for table `tblUserPasswordRequest` --- +-- CREATE TABLE `tblUserPasswordRequest` ( - `id` int(11) NOT NULL auto_increment, - `userID` int(11) NOT NULL default '0', - `hash` varchar(50) default NULL, - `date` datetime NOT NULL default '0000-00-00 00:00:00', - PRIMARY KEY (`id`), + `id` int(11) NOT NULL AUTO_INCREMENT, + `userID` int(11) NOT NULL DEFAULT '0', + `hash` varchar(50) DEFAULT NULL, + `date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`id`), + KEY `tblUserPasswordRequest_user` (`userID`), CONSTRAINT `tblUserPasswordRequest_user` FOREIGN KEY (`userID`) REFERENCES `tblUsers` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- --- +-- -- Table structure for table `tblUserPasswordHistory` --- +-- CREATE TABLE `tblUserPasswordHistory` ( - `id` int(11) NOT NULL auto_increment, - `userID` int(11) NOT NULL default '0', - `pwd` varchar(50) default NULL, - `date` datetime NOT NULL default '0000-00-00 00:00:00', - PRIMARY KEY (`id`), + `id` int(11) NOT NULL AUTO_INCREMENT, + `userID` int(11) NOT NULL DEFAULT '0', + `pwd` varchar(50) DEFAULT NULL, + `date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`id`), + KEY `tblUserPasswordHistory_user` (`userID`), CONSTRAINT `tblUserPasswordHistory_user` FOREIGN KEY (`userID`) REFERENCES `tblUsers` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- --- +-- -- Table structure for table `tblUserImages` --- +-- CREATE TABLE `tblUserImages` ( - `id` int(11) NOT NULL auto_increment, - `userID` int(11) NOT NULL default '0', + `id` int(11) NOT NULL AUTO_INCREMENT, + `userID` int(11) NOT NULL DEFAULT '0', `image` blob NOT NULL, - `mimeType` varchar(10) NOT NULL default '', - PRIMARY KEY (`id`), + `mimeType` varchar(10) NOT NULL DEFAULT '', + PRIMARY KEY (`id`), + KEY `tblUserImages_user` (`userID`), CONSTRAINT `tblUserImages_user` FOREIGN KEY (`userID`) REFERENCES `tblUsers` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- --- +-- -- Table structure for table `tblFolders` --- +-- CREATE TABLE `tblFolders` ( - `id` int(11) NOT NULL auto_increment, - `name` varchar(70) default NULL, - `parent` int(11) default NULL, + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(70) DEFAULT NULL, + `parent` int(11) DEFAULT NULL, `folderList` text NOT NULL, `comment` text, - `date` int(12) default NULL, - `owner` int(11) default NULL, - `inheritAccess` tinyint(1) NOT NULL default '1', - `defaultAccess` tinyint(4) NOT NULL default '0', - `sequence` double NOT NULL default '0', - PRIMARY KEY (`id`), + `date` int(12) DEFAULT NULL, + `owner` int(11) DEFAULT NULL, + `inheritAccess` tinyint(1) NOT NULL DEFAULT '1', + `defaultAccess` tinyint(4) NOT NULL DEFAULT '0', + `sequence` double NOT NULL DEFAULT '0', + PRIMARY KEY (`id`), KEY `parent` (`parent`), + KEY `tblFolders_owner` (`owner`), CONSTRAINT `tblFolders_owner` FOREIGN KEY (`owner`) REFERENCES `tblUsers` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -ALTER TABLE tblUsers ADD CONSTRAINT `tblUsers_homefolder` FOREIGN KEY (`homefolder`) REFERENCES `tblFolders` (`id`); +ALTER TABLE `tblUsers` ADD CONSTRAINT `tblUsers_homefolder` FOREIGN KEY (`homefolder`) REFERENCES `tblFolders` (`id`); -- -------------------------------------------------------- --- +-- -- Table structure for table `tblFolderAttributes` --- +-- CREATE TABLE `tblFolderAttributes` ( - `id` int(11) NOT NULL auto_increment, - `folder` int(11) default NULL, - `attrdef` int(11) default NULL, - `value` text default NULL, - PRIMARY KEY (`id`), - UNIQUE (folder, attrdef), - CONSTRAINT `tblFolderAttributes_folder` FOREIGN KEY (`folder`) REFERENCES `tblFolders` (`id`) ON DELETE CASCADE, - CONSTRAINT `tblFolderAttributes_attrdef` FOREIGN KEY (`attrdef`) REFERENCES `tblAttributeDefinitions` (`id`) + `id` int(11) NOT NULL AUTO_INCREMENT, + `folder` int(11) DEFAULT NULL, + `attrdef` int(11) DEFAULT NULL, + `value` text, + PRIMARY KEY (`id`), + UNIQUE KEY `folder` (`folder`,`attrdef`), + KEY `tblFolderAttributes_attrdef` (`attrdef`), + CONSTRAINT `tblFolderAttributes_attrdef` FOREIGN KEY (`attrdef`) REFERENCES `tblAttributeDefinitions` (`id`), + CONSTRAINT `tblFolderAttributes_folder` FOREIGN KEY (`folder`) REFERENCES `tblFolders` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- --- +-- -- Table structure for table `tblDocuments` --- +-- CREATE TABLE `tblDocuments` ( - `id` int(11) NOT NULL auto_increment, - `name` varchar(150) default NULL, + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(150) DEFAULT NULL, `comment` text, - `date` int(12) default NULL, - `expires` int(12) default NULL, - `owner` int(11) default NULL, - `folder` int(11) default NULL, + `date` int(12) DEFAULT NULL, + `expires` int(12) DEFAULT NULL, + `owner` int(11) DEFAULT NULL, + `folder` int(11) DEFAULT NULL, `folderList` text NOT NULL, - `inheritAccess` tinyint(1) NOT NULL default '1', - `defaultAccess` tinyint(4) NOT NULL default '0', - `locked` int(11) NOT NULL default '-1', + `inheritAccess` tinyint(1) NOT NULL DEFAULT '1', + `defaultAccess` tinyint(4) NOT NULL DEFAULT '0', + `locked` int(11) NOT NULL DEFAULT '-1', `keywords` text NOT NULL, - `sequence` double NOT NULL default '0', - PRIMARY KEY (`id`), + `sequence` double NOT NULL DEFAULT '0', + PRIMARY KEY (`id`), + KEY `tblDocuments_folder` (`folder`), + KEY `tblDocuments_owner` (`owner`), CONSTRAINT `tblDocuments_folder` FOREIGN KEY (`folder`) REFERENCES `tblFolders` (`id`), CONSTRAINT `tblDocuments_owner` FOREIGN KEY (`owner`) REFERENCES `tblUsers` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- --- +-- -- Table structure for table `tblDocumentAttributes` --- +-- CREATE TABLE `tblDocumentAttributes` ( - `id` int(11) NOT NULL auto_increment, - `document` int(11) default NULL, - `attrdef` int(11) default NULL, - `value` text default NULL, - PRIMARY KEY (`id`), - UNIQUE (document, attrdef), - CONSTRAINT `tblDocumentAttributes_document` FOREIGN KEY (`document`) REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE, - CONSTRAINT `tblDocumentAttributes_attrdef` FOREIGN KEY (`attrdef`) REFERENCES `tblAttributeDefinitions` (`id`) + `id` int(11) NOT NULL AUTO_INCREMENT, + `document` int(11) DEFAULT NULL, + `attrdef` int(11) DEFAULT NULL, + `value` text, + PRIMARY KEY (`id`), + UNIQUE KEY `document` (`document`,`attrdef`), + KEY `tblDocumentAttributes_attrdef` (`attrdef`), + CONSTRAINT `tblDocumentAttributes_attrdef` FOREIGN KEY (`attrdef`) REFERENCES `tblAttributeDefinitions` (`id`), + CONSTRAINT `tblDocumentAttributes_document` FOREIGN KEY (`document`) REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- --- +-- -- Table structure for table `tblDocumentApprovers` --- +-- CREATE TABLE `tblDocumentApprovers` ( - `approveID` int(11) NOT NULL auto_increment, - `documentID` int(11) NOT NULL default '0', - `version` smallint(5) unsigned NOT NULL default '0', - `type` tinyint(4) NOT NULL default '0', - `required` int(11) NOT NULL default '0', - PRIMARY KEY (`approveID`), + `approveID` int(11) NOT NULL AUTO_INCREMENT, + `documentID` int(11) NOT NULL DEFAULT '0', + `version` smallint(5) unsigned NOT NULL DEFAULT '0', + `type` tinyint(4) NOT NULL DEFAULT '0', + `required` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`approveID`), UNIQUE KEY `documentID` (`documentID`,`version`,`type`,`required`), CONSTRAINT `tblDocumentApprovers_document` FOREIGN KEY (`documentID`) REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- --- +-- -- Table structure for table `tblDocumentApproveLog` --- +-- CREATE TABLE `tblDocumentApproveLog` ( - `approveLogID` int(11) NOT NULL auto_increment, - `approveID` int(11) NOT NULL default '0', - `status` tinyint(4) NOT NULL default '0', + `approveLogID` int(11) NOT NULL AUTO_INCREMENT, + `approveID` int(11) NOT NULL DEFAULT '0', + `status` tinyint(4) NOT NULL DEFAULT '0', `comment` text NOT NULL, - `date` datetime NOT NULL default '0000-00-00 00:00:00', - `userID` int(11) NOT NULL default '0', - PRIMARY KEY (`approveLogID`), + `date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `userID` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`approveLogID`), + KEY `tblDocumentApproveLog_approve` (`approveID`), + KEY `tblDocumentApproveLog_user` (`userID`), CONSTRAINT `tblDocumentApproveLog_approve` FOREIGN KEY (`approveID`) REFERENCES `tblDocumentApprovers` (`approveID`) ON DELETE CASCADE, CONSTRAINT `tblDocumentApproveLog_user` FOREIGN KEY (`userID`) REFERENCES `tblUsers` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- --- +-- -- Table structure for table `tblDocumentContent` --- +-- CREATE TABLE `tblDocumentContent` ( - `id` int(11) NOT NULL auto_increment, - `document` int(11) NOT NULL default '0', + `id` int(11) NOT NULL AUTO_INCREMENT, + `document` int(11) NOT NULL DEFAULT '0', `version` smallint(5) unsigned NOT NULL, `comment` text, - `date` int(12) default NULL, - `createdBy` int(11) default NULL, - `dir` varchar(255) NOT NULL default '', - `orgFileName` varchar(150) NOT NULL default '', - `fileType` varchar(10) NOT NULL default '', - `mimeType` varchar(100) NOT NULL default '', - `fileSize` BIGINT, - `checksum` char(32), - PRIMARY KEY (`id`), - UNIQUE (`document`, `version`), + `date` int(12) DEFAULT NULL, + `createdBy` int(11) DEFAULT NULL, + `dir` varchar(255) NOT NULL DEFAULT '', + `orgFileName` varchar(150) NOT NULL DEFAULT '', + `fileType` varchar(10) NOT NULL DEFAULT '', + `mimeType` varchar(100) NOT NULL DEFAULT '', + `fileSize` bigint(20) DEFAULT NULL, + `checksum` char(32) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `document` (`document`,`version`), CONSTRAINT `tblDocumentContent_document` FOREIGN KEY (`document`) REFERENCES `tblDocuments` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- --- +-- -- Table structure for table `tblDocumentContentAttributes` --- +-- CREATE TABLE `tblDocumentContentAttributes` ( - `id` int(11) NOT NULL auto_increment, - `content` int(11) default NULL, - `attrdef` int(11) default NULL, - `value` text default NULL, - PRIMARY KEY (`id`), - UNIQUE (content, attrdef), - CONSTRAINT `tblDocumentContentAttributes_document` FOREIGN KEY (`content`) REFERENCES `tblDocumentContent` (`id`) ON DELETE CASCADE, - CONSTRAINT `tblDocumentContentAttributes_attrdef` FOREIGN KEY (`attrdef`) REFERENCES `tblAttributeDefinitions` (`id`) + `id` int(11) NOT NULL AUTO_INCREMENT, + `content` int(11) DEFAULT NULL, + `attrdef` int(11) DEFAULT NULL, + `value` text, + PRIMARY KEY (`id`), + UNIQUE KEY `content` (`content`,`attrdef`), + KEY `tblDocumentContentAttributes_attrdef` (`attrdef`), + CONSTRAINT `tblDocumentContentAttributes_attrdef` FOREIGN KEY (`attrdef`) REFERENCES `tblAttributeDefinitions` (`id`), + CONSTRAINT `tblDocumentContentAttributes_document` FOREIGN KEY (`content`) REFERENCES `tblDocumentContent` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- --- +-- -- Table structure for table `tblDocumentLinks` --- +-- CREATE TABLE `tblDocumentLinks` ( - `id` int(11) NOT NULL auto_increment, - `document` int(11) NOT NULL default '0', - `target` int(11) NOT NULL default '0', - `userID` int(11) NOT NULL default '0', - `public` tinyint(1) NOT NULL default '0', - PRIMARY KEY (`id`), + `id` int(11) NOT NULL AUTO_INCREMENT, + `document` int(11) NOT NULL DEFAULT '0', + `target` int(11) NOT NULL DEFAULT '0', + `userID` int(11) NOT NULL DEFAULT '0', + `public` tinyint(1) NOT NULL DEFAULT '0', + PRIMARY KEY (`id`), + KEY `tblDocumentLinks_document` (`document`), + KEY `tblDocumentLinks_target` (`target`), + KEY `tblDocumentLinks_user` (`userID`), CONSTRAINT `tblDocumentLinks_document` FOREIGN KEY (`document`) REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE, CONSTRAINT `tblDocumentLinks_target` FOREIGN KEY (`target`) REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE, CONSTRAINT `tblDocumentLinks_user` FOREIGN KEY (`userID`) REFERENCES `tblUsers` (`id`) @@ -294,415 +308,441 @@ CREATE TABLE `tblDocumentLinks` ( -- -------------------------------------------------------- --- +-- -- Table structure for table `tblDocumentFiles` --- +-- CREATE TABLE `tblDocumentFiles` ( - `id` int(11) NOT NULL auto_increment, - `document` int(11) NOT NULL default '0', - `userID` int(11) NOT NULL default '0', + `id` int(11) NOT NULL AUTO_INCREMENT, + `document` int(11) NOT NULL DEFAULT '0', + `userID` int(11) NOT NULL DEFAULT '0', `comment` text, - `name` varchar(150) default NULL, - `date` int(12) default NULL, - `dir` varchar(255) NOT NULL default '', - `orgFileName` varchar(150) NOT NULL default '', - `fileType` varchar(10) NOT NULL default '', - `mimeType` varchar(100) NOT NULL default '', - PRIMARY KEY (`id`), + `name` varchar(150) DEFAULT NULL, + `date` int(12) DEFAULT NULL, + `dir` varchar(255) NOT NULL DEFAULT '', + `orgFileName` varchar(150) NOT NULL DEFAULT '', + `fileType` varchar(10) NOT NULL DEFAULT '', + `mimeType` varchar(100) NOT NULL DEFAULT '', + PRIMARY KEY (`id`), + KEY `tblDocumentFiles_document` (`document`), + KEY `tblDocumentFiles_user` (`userID`), CONSTRAINT `tblDocumentFiles_document` FOREIGN KEY (`document`) REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE, CONSTRAINT `tblDocumentFiles_user` FOREIGN KEY (`userID`) REFERENCES `tblUsers` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; - - -- -------------------------------------------------------- --- +-- -- Table structure for table `tblDocumentLocks` --- +-- CREATE TABLE `tblDocumentLocks` ( - `document` int(11) NOT NULL default '0', - `userID` int(11) NOT NULL default '0', - PRIMARY KEY (`document`), + `document` int(11) NOT NULL DEFAULT '0', + `userID` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`document`), + KEY `tblDocumentLocks_user` (`userID`), CONSTRAINT `tblDocumentLocks_document` FOREIGN KEY (`document`) REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE, CONSTRAINT `tblDocumentLocks_user` FOREIGN KEY (`userID`) REFERENCES `tblUsers` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- --- +-- -- Table structure for table `tblDocumentReviewers` --- +-- CREATE TABLE `tblDocumentReviewers` ( - `reviewID` int(11) NOT NULL auto_increment, - `documentID` int(11) NOT NULL default '0', - `version` smallint(5) unsigned NOT NULL default '0', - `type` tinyint(4) NOT NULL default '0', - `required` int(11) NOT NULL default '0', - PRIMARY KEY (`reviewID`), + `reviewID` int(11) NOT NULL AUTO_INCREMENT, + `documentID` int(11) NOT NULL DEFAULT '0', + `version` smallint(5) unsigned NOT NULL DEFAULT '0', + `type` tinyint(4) NOT NULL DEFAULT '0', + `required` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`reviewID`), UNIQUE KEY `documentID` (`documentID`,`version`,`type`,`required`), CONSTRAINT `tblDocumentReviewers_document` FOREIGN KEY (`documentID`) REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- --- +-- -- Table structure for table `tblDocumentReviewLog` --- +-- CREATE TABLE `tblDocumentReviewLog` ( - `reviewLogID` int(11) NOT NULL auto_increment, - `reviewID` int(11) NOT NULL default '0', - `status` tinyint(4) NOT NULL default '0', + `reviewLogID` int(11) NOT NULL AUTO_INCREMENT, + `reviewID` int(11) NOT NULL DEFAULT '0', + `status` tinyint(4) NOT NULL DEFAULT '0', `comment` text NOT NULL, - `date` datetime NOT NULL default '0000-00-00 00:00:00', - `userID` int(11) NOT NULL default '0', - PRIMARY KEY (`reviewLogID`), + `date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `userID` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`reviewLogID`), + KEY `tblDocumentReviewLog_review` (`reviewID`), + KEY `tblDocumentReviewLog_user` (`userID`), CONSTRAINT `tblDocumentReviewLog_review` FOREIGN KEY (`reviewID`) REFERENCES `tblDocumentReviewers` (`reviewID`) ON DELETE CASCADE, CONSTRAINT `tblDocumentReviewLog_user` FOREIGN KEY (`userID`) REFERENCES `tblUsers` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- --- +-- -- Table structure for table `tblDocumentStatus` --- +-- CREATE TABLE `tblDocumentStatus` ( - `statusID` int(11) NOT NULL auto_increment, - `documentID` int(11) NOT NULL default '0', - `version` smallint(5) unsigned NOT NULL default '0', - PRIMARY KEY (`statusID`), + `statusID` int(11) NOT NULL AUTO_INCREMENT, + `documentID` int(11) NOT NULL DEFAULT '0', + `version` smallint(5) unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (`statusID`), UNIQUE KEY `documentID` (`documentID`,`version`), CONSTRAINT `tblDocumentStatus_document` FOREIGN KEY (`documentID`) REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- --- +-- -- Table structure for table `tblDocumentStatusLog` --- +-- CREATE TABLE `tblDocumentStatusLog` ( - `statusLogID` int(11) NOT NULL auto_increment, - `statusID` int(11) NOT NULL default '0', - `status` tinyint(4) NOT NULL default '0', + `statusLogID` int(11) NOT NULL AUTO_INCREMENT, + `statusID` int(11) NOT NULL DEFAULT '0', + `status` tinyint(4) NOT NULL DEFAULT '0', `comment` text NOT NULL, - `date` datetime NOT NULL default '0000-00-00 00:00:00', - `userID` int(11) NOT NULL default '0', - PRIMARY KEY (`statusLogID`), + `date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `userID` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`statusLogID`), KEY `statusID` (`statusID`), + KEY `tblDocumentStatusLog_user` (`userID`), CONSTRAINT `tblDocumentStatusLog_status` FOREIGN KEY (`statusID`) REFERENCES `tblDocumentStatus` (`statusID`) ON DELETE CASCADE, CONSTRAINT `tblDocumentStatusLog_user` FOREIGN KEY (`userID`) REFERENCES `tblUsers` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- --- +-- -- Table structure for table `tblGroups` --- +-- CREATE TABLE `tblGroups` ( - `id` int(11) NOT NULL auto_increment, - `name` varchar(50) default NULL, + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(50) DEFAULT NULL, `comment` text NOT NULL, - PRIMARY KEY (`id`) + PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- --- +-- -- Table structure for table `tblGroupMembers` --- +-- CREATE TABLE `tblGroupMembers` ( - `groupID` int(11) NOT NULL default '0', - `userID` int(11) NOT NULL default '0', - `manager` smallint(1) NOT NULL default '0', - UNIQUE (`groupID`,`userID`), - CONSTRAINT `tblGroupMembers_user` FOREIGN KEY (`userID`) REFERENCES `tblUsers` (`id`) ON DELETE CASCADE, - CONSTRAINT `tblGroupMembers_group` FOREIGN KEY (`groupID`) REFERENCES `tblGroups` (`id`) ON DELETE CASCADE + `groupID` int(11) NOT NULL DEFAULT '0', + `userID` int(11) NOT NULL DEFAULT '0', + `manager` smallint(1) NOT NULL DEFAULT '0', + UNIQUE KEY `groupID` (`groupID`,`userID`), + KEY `tblGroupMembers_user` (`userID`), + CONSTRAINT `tblGroupMembers_group` FOREIGN KEY (`groupID`) REFERENCES `tblGroups` (`id`) ON DELETE CASCADE, + CONSTRAINT `tblGroupMembers_user` FOREIGN KEY (`userID`) REFERENCES `tblUsers` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- --- +-- -- Table structure for table `tblKeywordCategories` --- +-- CREATE TABLE `tblKeywordCategories` ( - `id` int(11) NOT NULL auto_increment, - `name` varchar(255) NOT NULL default '', - `owner` int(11) NOT NULL default '0', - PRIMARY KEY (`id`) + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL DEFAULT '', + `owner` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- --- +-- -- Table structure for table `tblKeywords` --- +-- CREATE TABLE `tblKeywords` ( - `id` int(11) NOT NULL auto_increment, - `category` int(11) NOT NULL default '0', + `id` int(11) NOT NULL AUTO_INCREMENT, + `category` int(11) NOT NULL DEFAULT '0', `keywords` text NOT NULL, - PRIMARY KEY (`id`), + PRIMARY KEY (`id`), + KEY `tblKeywords_category` (`category`), CONSTRAINT `tblKeywords_category` FOREIGN KEY (`category`) REFERENCES `tblKeywordCategories` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- --- +-- -- Table structure for table `tblDocumentCategory` --- +-- CREATE TABLE `tblDocumentCategory` ( - `categoryID` int(11) NOT NULL default 0, - `documentID` int(11) NOT NULL default 0, + `categoryID` int(11) NOT NULL DEFAULT '0', + `documentID` int(11) NOT NULL DEFAULT '0', + KEY `tblDocumentCategory_category` (`categoryID`), + KEY `tblDocumentCategory_document` (`documentID`), CONSTRAINT `tblDocumentCategory_category` FOREIGN KEY (`categoryID`) REFERENCES `tblCategory` (`id`) ON DELETE CASCADE, CONSTRAINT `tblDocumentCategory_document` FOREIGN KEY (`documentID`) REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- --- +-- -- Table structure for table `tblNotify` --- +-- CREATE TABLE `tblNotify` ( - `target` int(11) NOT NULL default '0', - `targetType` int(11) NOT NULL default '0', - `userID` int(11) NOT NULL default '-1', - `groupID` int(11) NOT NULL default '-1', - PRIMARY KEY (`target`,`targetType`,`userID`,`groupID`) + `target` int(11) NOT NULL DEFAULT '0', + `targetType` int(11) NOT NULL DEFAULT '0', + `userID` int(11) NOT NULL DEFAULT '-1', + `groupID` int(11) NOT NULL DEFAULT '-1', + PRIMARY KEY (`target`,`targetType`,`userID`,`groupID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- --- +-- -- Table structure for table `tblSessions` --- +-- CREATE TABLE `tblSessions` ( - `id` varchar(50) NOT NULL default '', - `userID` int(11) NOT NULL default '0', - `lastAccess` int(11) NOT NULL default '0', - `theme` varchar(30) NOT NULL default '', - `language` varchar(30) NOT NULL default '', - `clipboard` text default NULL, - `su` INTEGER DEFAULT NULL, - `splashmsg` text default NULL, - PRIMARY KEY (`id`), + `id` varchar(50) NOT NULL DEFAULT '', + `userID` int(11) NOT NULL DEFAULT '0', + `lastAccess` int(11) NOT NULL DEFAULT '0', + `theme` varchar(30) NOT NULL DEFAULT '', + `language` varchar(30) NOT NULL DEFAULT '', + `clipboard` text, + `su` int(11) DEFAULT NULL, + `splashmsg` text, + PRIMARY KEY (`id`), + KEY `tblSessions_user` (`userID`), CONSTRAINT `tblSessions_user` FOREIGN KEY (`userID`) REFERENCES `tblUsers` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- --- --- Table structure for mandatory reviewers --- +-- +-- Table structure for table `tblMandatoryReviewers` +-- CREATE TABLE `tblMandatoryReviewers` ( - `userID` int(11) NOT NULL default '0', - `reviewerUserID` int(11) NOT NULL default '0', - `reviewerGroupID` int(11) NOT NULL default '0', - PRIMARY KEY (`userID`,`reviewerUserID`,`reviewerGroupID`), + `userID` int(11) NOT NULL DEFAULT '0', + `reviewerUserID` int(11) NOT NULL DEFAULT '0', + `reviewerGroupID` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`userID`,`reviewerUserID`,`reviewerGroupID`), CONSTRAINT `tblMandatoryReviewers_user` FOREIGN KEY (`userID`) REFERENCES `tblUsers` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- --- --- Table structure for mandatory approvers --- +-- +-- Table structure for table `tblMandatoryApprovers` +-- CREATE TABLE `tblMandatoryApprovers` ( - `userID` int(11) NOT NULL default '0', - `approverUserID` int(11) NOT NULL default '0', - `approverGroupID` int(11) NOT NULL default '0', - PRIMARY KEY (`userID`,`approverUserID`,`approverGroupID`), + `userID` int(11) NOT NULL DEFAULT '0', + `approverUserID` int(11) NOT NULL DEFAULT '0', + `approverGroupID` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`userID`,`approverUserID`,`approverGroupID`), CONSTRAINT `tblMandatoryApprovers_user` FOREIGN KEY (`userID`) REFERENCES `tblUsers` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- --- --- Table structure for events (calendar) --- +-- +-- Table structure for table `tblEvents` +-- CREATE TABLE `tblEvents` ( - `id` int(11) NOT NULL auto_increment, - `name` varchar(150) default NULL, + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(150) DEFAULT NULL, `comment` text, - `start` int(12) default NULL, - `stop` int(12) default NULL, - `date` int(12) default NULL, - `userID` int(11) NOT NULL default '0', - PRIMARY KEY (`id`) + `start` int(12) DEFAULT NULL, + `stop` int(12) DEFAULT NULL, + `date` int(12) DEFAULT NULL, + `userID` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- --- --- Table structure for workflow states --- +-- +-- Table structure for table `tblWorkflowStates` +-- -CREATE TABLE tblWorkflowStates ( - `id` int(11) NOT NULL auto_increment, +CREATE TABLE `tblWorkflowStates` ( + `id` int(11) NOT NULL AUTO_INCREMENT, `name` text NOT NULL, - `visibility` smallint(5) DEFAULT 0, - `maxtime` int(11) DEFAULT 0, - `precondfunc` text DEFAULT NULL, + `visibility` smallint(5) DEFAULT '0', + `maxtime` int(11) DEFAULT '0', + `precondfunc` text, `documentstatus` smallint(5) DEFAULT NULL, - PRIMARY KEY (`id`) + PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- --- --- Table structure for workflow actions --- +-- +-- Table structure for table `tblWorkflowActions` +-- -CREATE TABLE tblWorkflowActions ( - `id` int(11) NOT NULL auto_increment, +CREATE TABLE `tblWorkflowActions` ( + `id` int(11) NOT NULL AUTO_INCREMENT, `name` text NOT NULL, - PRIMARY KEY (`id`) + PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- --- --- Table structure for workflows --- +-- +-- Table structure for table `tblWorkflows` +-- -CREATE TABLE tblWorkflows ( - `id` int(11) NOT NULL auto_increment, +CREATE TABLE `tblWorkflows` ( + `id` int(11) NOT NULL AUTO_INCREMENT, `name` text NOT NULL, `initstate` int(11) NOT NULL, - PRIMARY KEY (`id`), + PRIMARY KEY (`id`), + KEY `tblWorkflow_initstate` (`initstate`), CONSTRAINT `tblWorkflow_initstate` FOREIGN KEY (`initstate`) REFERENCES `tblWorkflowStates` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- --- --- Table structure for workflow transitions --- +-- +-- Table structure for table `tblWorkflowTransitions` +-- -CREATE TABLE tblWorkflowTransitions ( - `id` int(11) NOT NULL auto_increment, - `workflow` int(11) default NULL, - `state` int(11) default NULL, - `action` int(11) default NULL, - `nextstate` int(11) default NULL, - `maxtime` int(11) DEFAULT 0, - PRIMARY KEY (`id`), - CONSTRAINT `tblWorkflowTransitions_workflow` FOREIGN KEY (`workflow`) REFERENCES `tblWorkflows` (`id`) ON DELETE CASCADE, - CONSTRAINT `tblWorkflowTransitions_state` FOREIGN KEY (`state`) REFERENCES `tblWorkflowStates` (`id`) ON DELETE CASCADE, +CREATE TABLE `tblWorkflowTransitions` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `workflow` int(11) DEFAULT NULL, + `state` int(11) DEFAULT NULL, + `action` int(11) DEFAULT NULL, + `nextstate` int(11) DEFAULT NULL, + `maxtime` int(11) DEFAULT '0', + PRIMARY KEY (`id`), + KEY `tblWorkflowTransitions_workflow` (`workflow`), + KEY `tblWorkflowTransitions_state` (`state`), + KEY `tblWorkflowTransitions_action` (`action`), + KEY `tblWorkflowTransitions_nextstate` (`nextstate`), CONSTRAINT `tblWorkflowTransitions_action` FOREIGN KEY (`action`) REFERENCES `tblWorkflowActions` (`id`) ON DELETE CASCADE, - CONSTRAINT `tblWorkflowTransitions_nextstate` FOREIGN KEY (`nextstate`) REFERENCES `tblWorkflowStates` (`id`) ON DELETE CASCADE + CONSTRAINT `tblWorkflowTransitions_nextstate` FOREIGN KEY (`nextstate`) REFERENCES `tblWorkflowStates` (`id`) ON DELETE CASCADE, + CONSTRAINT `tblWorkflowTransitions_state` FOREIGN KEY (`state`) REFERENCES `tblWorkflowStates` (`id`) ON DELETE CASCADE, + CONSTRAINT `tblWorkflowTransitions_workflow` FOREIGN KEY (`workflow`) REFERENCES `tblWorkflows` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- --- --- Table structure for workflow transition users --- +-- +-- Table structure for table `tblWorkflowTransitionUsers` +-- -CREATE TABLE tblWorkflowTransitionUsers ( - `id` int(11) NOT NULL auto_increment, - `transition` int(11) default NULL, - `userid` int(11) default NULL, - PRIMARY KEY (`id`), +CREATE TABLE `tblWorkflowTransitionUsers` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `transition` int(11) DEFAULT NULL, + `userid` int(11) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `tblWorkflowTransitionUsers_transition` (`transition`), + KEY `tblWorkflowTransitionUsers_userid` (`userid`), CONSTRAINT `tblWorkflowTransitionUsers_transition` FOREIGN KEY (`transition`) REFERENCES `tblWorkflowTransitions` (`id`) ON DELETE CASCADE, CONSTRAINT `tblWorkflowTransitionUsers_userid` FOREIGN KEY (`userid`) REFERENCES `tblUsers` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- --- --- Table structure for workflow transition groups --- +-- +-- Table structure for table `tblWorkflowTransitionGroups` +-- -CREATE TABLE tblWorkflowTransitionGroups ( - `id` int(11) NOT NULL auto_increment, - `transition` int(11) default NULL, - `groupid` int(11) default NULL, - `minusers` int(11) default NULL, - PRIMARY KEY (`id`), - CONSTRAINT `tblWorkflowTransitionGroups_transition` FOREIGN KEY (`transition`) REFERENCES `tblWorkflowTransitions` (`id`) ON DELETE CASCADE, - CONSTRAINT `tblWorkflowTransitionGroups_groupid` FOREIGN KEY (`groupID`) REFERENCES `tblGroups` (`id`) ON DELETE CASCADE +CREATE TABLE `tblWorkflowTransitionGroups` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `transition` int(11) DEFAULT NULL, + `groupid` int(11) DEFAULT NULL, + `minusers` int(11) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `tblWorkflowTransitionGroups_transition` (`transition`), + KEY `tblWorkflowTransitionGroups_groupid` (`groupid`), + CONSTRAINT `tblWorkflowTransitionGroups_groupid` FOREIGN KEY (`groupid`) REFERENCES `tblGroups` (`id`) ON DELETE CASCADE, + CONSTRAINT `tblWorkflowTransitionGroups_transition` FOREIGN KEY (`transition`) REFERENCES `tblWorkflowTransitions` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- --- --- Table structure for workflow log --- +-- +-- Table structure for table `tblWorkflowLog` +-- -CREATE TABLE tblWorkflowLog ( - `id` int(11) NOT NULL auto_increment, - `document` int(11) default NULL, - `version` smallint(5) default NULL, - `workflow` int(11) default NULL, - `userid` int(11) default NULL, - `transition` int(11) default NULL, - `date` datetime NOT NULL default '0000-00-00 00:00:00', +CREATE TABLE `tblWorkflowLog` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `document` int(11) DEFAULT NULL, + `version` smallint(5) DEFAULT NULL, + `workflow` int(11) DEFAULT NULL, + `userid` int(11) DEFAULT NULL, + `transition` int(11) DEFAULT NULL, + `date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `comment` text, - PRIMARY KEY (`id`), + PRIMARY KEY (`id`), + KEY `tblWorkflowLog_document` (`document`), + KEY `tblWorkflowLog_workflow` (`workflow`), + KEY `tblWorkflowLog_userid` (`userid`), + KEY `tblWorkflowLog_transition` (`transition`), CONSTRAINT `tblWorkflowLog_document` FOREIGN KEY (`document`) REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE, - CONSTRAINT `tblWorkflowLog_workflow` FOREIGN KEY (`workflow`) REFERENCES `tblWorkflows` (`id`) ON DELETE CASCADE, + CONSTRAINT `tblWorkflowLog_transition` FOREIGN KEY (`transition`) REFERENCES `tblWorkflowTransitions` (`id`) ON DELETE CASCADE, CONSTRAINT `tblWorkflowLog_userid` FOREIGN KEY (`userid`) REFERENCES `tblUsers` (`id`) ON DELETE CASCADE, - CONSTRAINT `tblWorkflowLog_transition` FOREIGN KEY (`transition`) REFERENCES `tblWorkflowTransitions` (`id`) ON DELETE CASCADE + CONSTRAINT `tblWorkflowLog_workflow` FOREIGN KEY (`workflow`) REFERENCES `tblWorkflows` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- --- --- Table structure for workflow document relation --- +-- +-- Table structure for table `tblWorkflowDocumentContent` +-- -CREATE TABLE tblWorkflowDocumentContent ( - `parentworkflow` int(11) DEFAULT 0, +CREATE TABLE `tblWorkflowDocumentContent` ( + `parentworkflow` int(11) DEFAULT '0', `workflow` int(11) DEFAULT NULL, `document` int(11) DEFAULT NULL, `version` smallint(5) DEFAULT NULL, `state` int(11) DEFAULT NULL, - `date` datetime NOT NULL default '0000-00-00 00:00:00', + `date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + KEY `tblWorkflowDocument_document` (`document`), + KEY `tblWorkflowDocument_workflow` (`workflow`), + KEY `tblWorkflowDocument_state` (`state`), CONSTRAINT `tblWorkflowDocument_document` FOREIGN KEY (`document`) REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE, - CONSTRAINT `tblWorkflowDocument_workflow` FOREIGN KEY (`workflow`) REFERENCES `tblWorkflows` (`id`) ON DELETE CASCADE, - CONSTRAINT `tblWorkflowDocument_state` FOREIGN KEY (`state`) REFERENCES `tblWorkflowStates` (`id`) ON DELETE CASCADE + CONSTRAINT `tblWorkflowDocument_state` FOREIGN KEY (`state`) REFERENCES `tblWorkflowStates` (`id`) ON DELETE CASCADE, + CONSTRAINT `tblWorkflowDocument_workflow` FOREIGN KEY (`workflow`) REFERENCES `tblWorkflows` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- --- --- Table structure for mandatory workflows --- +-- +-- Table structure for table `tblWorkflowMandatoryWorkflow` +-- -CREATE TABLE tblWorkflowMandatoryWorkflow ( - `userid` int(11) default NULL, - `workflow` int(11) default NULL, - UNIQUE(userid, workflow), - CONSTRAINT `tblWorkflowMandatoryWorkflow_workflow` FOREIGN KEY (`workflow`) REFERENCES `tblWorkflows` (`id`) ON DELETE CASCADE, - CONSTRAINT `tblWorkflowMandatoryWorkflow_userid` FOREIGN KEY (`userid`) REFERENCES `tblUsers` (`id`) ON DELETE CASCADE +CREATE TABLE `tblWorkflowMandatoryWorkflow` ( + `userid` int(11) DEFAULT NULL, + `workflow` int(11) DEFAULT NULL, + UNIQUE KEY `userid` (`userid`,`workflow`), + KEY `tblWorkflowMandatoryWorkflow_workflow` (`workflow`), + CONSTRAINT `tblWorkflowMandatoryWorkflow_userid` FOREIGN KEY (`userid`) REFERENCES `tblUsers` (`id`) ON DELETE CASCADE, + CONSTRAINT `tblWorkflowMandatoryWorkflow_workflow` FOREIGN KEY (`workflow`) REFERENCES `tblWorkflows` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- --- --- Table structure for version --- +-- +-- Table structure for table `tblVersion` +-- CREATE TABLE `tblVersion` ( - `date` datetime, - `major` smallint, - `minor` smallint, - `subminor` smallint + `date` datetime NOT NULL, + `major` smallint(6) DEFAULT NULL, + `minor` smallint(6) DEFAULT NULL, + `subminor` smallint(6) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- @@ -715,4 +755,3 @@ INSERT INTO tblUsers VALUES (1, 'admin', '21232f297a57a5a743894a0e4a801fc3', 'Ad INSERT INTO tblUsers VALUES (2, 'guest', NULL, 'Guest User', NULL, '', '', '', 2, 0, '0000-00-00 00:00:00', 0, 0, 0, NULL); INSERT INTO tblFolders VALUES (1, 'DMS', 0, '', 'DMS root', UNIX_TIMESTAMP(), 1, 0, 2, 0); INSERT INTO tblVersion VALUES (NOW(), 5, 0, 0); -INSERT INTO tblCategory VALUES (0, ''); diff --git a/install/create_tables-sqlite3.sql b/install/create_tables-sqlite3.sql index 43623a436..64b517fd1 100644 --- a/install/create_tables-sqlite3.sql +++ b/install/create_tables-sqlite3.sql @@ -286,21 +286,6 @@ CREATE TABLE `tblDocumentLocks` ( -- -------------------------------------------------------- --- --- Table structure for table `tblDocumentReviewLog` --- - -CREATE TABLE `tblDocumentReviewLog` ( - `reviewLogID` INTEGER PRIMARY KEY AUTOINCREMENT, - `reviewID` INTEGER NOT NULL default 0 REFERENCES `tblDocumentReviewers` (`reviewID`) ON DELETE CASCADE, - `status` INTEGER NOT NULL default 0, - `comment` TEXT NOT NULL, - `date` TEXT NOT NULL default '0000-00-00 00:00:00', - `userID` INTEGER NOT NULL default 0 REFERENCES `tblUsers` (`id`) ON DELETE CASCADE -) ; - --- -------------------------------------------------------- - -- -- Table structure for table `tblDocumentReviewers` -- @@ -316,6 +301,21 @@ CREATE TABLE `tblDocumentReviewers` ( -- -------------------------------------------------------- +-- +-- Table structure for table `tblDocumentReviewLog` +-- + +CREATE TABLE `tblDocumentReviewLog` ( + `reviewLogID` INTEGER PRIMARY KEY AUTOINCREMENT, + `reviewID` INTEGER NOT NULL default 0 REFERENCES `tblDocumentReviewers` (`reviewID`) ON DELETE CASCADE, + `status` INTEGER NOT NULL default 0, + `comment` TEXT NOT NULL, + `date` TEXT NOT NULL default '0000-00-00 00:00:00', + `userID` INTEGER NOT NULL default 0 REFERENCES `tblUsers` (`id`) ON DELETE CASCADE +) ; + +-- -------------------------------------------------------- + -- -- Table structure for table `tblDocumentStatus` -- @@ -481,13 +481,13 @@ CREATE TABLE `tblEvents` ( -- Table structure for workflow states -- -CREATE TABLE tblWorkflowStates ( +CREATE TABLE `tblWorkflowStates` ( `id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` text NOT NULL, - `visibility` smallint(5) DEFAULT 0, + `visibility` INTEGER DEFAULT 0, `maxtime` INTEGER DEFAULT 0, `precondfunc` text DEFAULT NULL, - `documentstatus` smallint(5) DEFAULT NULL + `documentstatus` INTEGER DEFAULT NULL ) ; -- -------------------------------------------------------- @@ -496,7 +496,7 @@ CREATE TABLE tblWorkflowStates ( -- Table structure for workflow actions -- -CREATE TABLE tblWorkflowActions ( +CREATE TABLE `tblWorkflowActions` ( `id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` text NOT NULL ) ; @@ -507,7 +507,7 @@ CREATE TABLE tblWorkflowActions ( -- Table structure for workflows -- -CREATE TABLE tblWorkflows ( +CREATE TABLE `tblWorkflows` ( `id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` text NOT NULL, `initstate` INTEGER NOT NULL REFERENCES `tblWorkflowStates` (`id`) ON DELETE CASCADE @@ -519,7 +519,7 @@ CREATE TABLE tblWorkflows ( -- Table structure for workflow transitions -- -CREATE TABLE tblWorkflowTransitions ( +CREATE TABLE `tblWorkflowTransitions` ( `id` INTEGER PRIMARY KEY AUTOINCREMENT, `workflow` INTEGER default NULL REFERENCES `tblWorkflows` (`id`) ON DELETE CASCADE, `state` INTEGER default NULL REFERENCES `tblWorkflowStates` (`id`) ON DELETE CASCADE, @@ -534,7 +534,7 @@ CREATE TABLE tblWorkflowTransitions ( -- Table structure for workflow transition users -- -CREATE TABLE tblWorkflowTransitionUsers ( +CREATE TABLE `tblWorkflowTransitionUsers` ( `id` INTEGER PRIMARY KEY AUTOINCREMENT, `transition` INTEGER default NULL REFERENCES `tblWorkflowTransitions` (`id`) ON DELETE CASCADE, `userid` INTEGER default NULL REFERENCES `tblUsers` (`id`) ON DELETE CASCADE @@ -546,7 +546,7 @@ CREATE TABLE tblWorkflowTransitionUsers ( -- Table structure for workflow transition groups -- -CREATE TABLE tblWorkflowTransitionGroups ( +CREATE TABLE `tblWorkflowTransitionGroups` ( `id` INTEGER PRIMARY KEY AUTOINCREMENT, `transition` INTEGER default NULL REFERENCES `tblWorkflowTransitions` (`id`) ON DELETE CASCADE, `groupid` INTEGER default NULL REFERENCES `tblGroups` (`id`) ON DELETE CASCADE, @@ -559,10 +559,10 @@ CREATE TABLE tblWorkflowTransitionGroups ( -- Table structure for workflow log -- -CREATE TABLE tblWorkflowLog ( +CREATE TABLE `tblWorkflowLog` ( `id` INTEGER PRIMARY KEY AUTOINCREMENT, `document` INTEGER default NULL REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE, - `version` smallint default NULL, + `version` INTEGER default NULL, `workflow` INTEGER default NULL REFERENCES `tblWorkflows` (`id`) ON DELETE CASCADE, `userid` INTEGER default NULL REFERENCES `tblUsers` (`id`) ON DELETE CASCADE, `transition` INTEGER default NULL REFERENCES `tblWorkflowTransitions` (`id`) ON DELETE CASCADE, @@ -576,11 +576,11 @@ CREATE TABLE tblWorkflowLog ( -- Table structure for workflow document relation -- -CREATE TABLE tblWorkflowDocumentContent ( +CREATE TABLE `tblWorkflowDocumentContent` ( `parentworkflow` INTEGER DEFAULT 0, `workflow` INTEGER DEFAULT NULL REFERENCES `tblWorkflows` (`id`) ON DELETE CASCADE, `document` INTEGER DEFAULT NULL REFERENCES `tblDocuments` (`id`) ON DELETE CASCADE, - `version` smallint DEFAULT NULL, + `version` INTEGER DEFAULT NULL, `state` INTEGER DEFAULT NULL REFERENCES `tblWorkflowStates` (`id`) ON DELETE CASCADE, `date` datetime NOT NULL default '0000-00-00 00:00:00' ) ; @@ -591,7 +591,7 @@ CREATE TABLE tblWorkflowDocumentContent ( -- Table structure for mandatory workflows -- -CREATE TABLE tblWorkflowMandatoryWorkflow ( +CREATE TABLE `tblWorkflowMandatoryWorkflow` ( `userid` INTEGER default NULL REFERENCES `tblUsers` (`id`) ON DELETE CASCADE, `workflow` INTEGER default NULL REFERENCES `tblWorkflows` (`id`) ON DELETE CASCADE, UNIQUE(userid, workflow) @@ -605,9 +605,9 @@ CREATE TABLE tblWorkflowMandatoryWorkflow ( CREATE TABLE `tblVersion` ( `date` TEXT NOT NULL default '0000-00-00 00:00:00', - `major` smallint, - `minor` smallint, - `subminor` smallint + `major` INTEGER, + `minor` INTEGER, + `subminor` INTEGER ) ; -- -------------------------------------------------------- @@ -620,4 +620,3 @@ INSERT INTO tblUsers VALUES (1, 'admin', '21232f297a57a5a743894a0e4a801fc3', 'Ad INSERT INTO tblUsers VALUES (2, 'guest', NULL, 'Guest User', NULL, '', '', '', 2, 0, '', 0, 0, 0, 0); INSERT INTO tblFolders VALUES (1, 'DMS', 0, '', 'DMS root', strftime('%s','now'), 1, 0, 2, 0); INSERT INTO tblVersion VALUES (DATETIME(), 5, 0, 0); -INSERT INTO tblCategory VALUES (0, ''); diff --git a/install/install.php b/install/install.php index 92139344e..726cdd341 100644 --- a/install/install.php +++ b/install/install.php @@ -118,7 +118,7 @@ function fileExistsInIncludePath($file) { /* {{{ */ * Load default settings + set */ define("SEEDDMS_INSTALL", "on"); -define("SEEDDMS_VERSION", "5.0.9"); +define("SEEDDMS_VERSION", "5.0.10"); require_once('../inc/inc.ClassSettings.php'); diff --git a/install/update.php b/install/update.php index afc7e3e46..23e1714ce 100644 --- a/install/update.php +++ b/install/update.php @@ -33,11 +33,14 @@ if (!file_exists($configDir."/ENABLE_INSTALL_TOOL")) { exit; } -$theme = "blue"; +$theme = "bootstrap"; require_once("../inc/inc.Language.php"); +include "../languages/en_GB/lang.inc"; require_once("../inc/inc.ClassUI.php"); UI::htmlStartPage('Database update'); +UI::globalBanner(); +UI::contentStart(); UI::contentHeading("SeedDMS Installation for version ".$_GET['version']); UI::contentContainerStart(); @@ -104,6 +107,11 @@ if($rec = $res->fetch(PDO::FETCH_ASSOC)) { } $db = null; +// just remove info for web page installation +$settings->_printDisclaimer = false; +$settings->_footNote = false; +// end of the page UI::contentContainerEnd(); +UI::contentEnd(); UI::htmlEndPage(); ?> diff --git a/languages/ar_EG/lang.inc b/languages/ar_EG/lang.inc index ef963df37..df70ad26b 100644 --- a/languages/ar_EG/lang.inc +++ b/languages/ar_EG/lang.inc @@ -541,8 +541,13 @@ URL: [url]', 'include_content' => '', 'include_documents' => 'اشمل مستندات', 'include_subdirectories' => 'اشمل مجلدات فرعية', +'indexing_tasks_in_queue' => '', 'index_converters' => 'فهرس تحويل المستند', +'index_done' => '', +'index_error' => '', 'index_folder' => 'ﻒﻫﺮﺳﺓ ﺎﻠﻤﺠﻟﺩ', +'index_pending' => '', +'index_waiting' => '', 'individuals' => 'افراد', 'indivіduals_in_groups' => '', 'inherited' => 'موروث', @@ -761,6 +766,7 @@ URL: [url]', 'only_jpg_user_images' => 'فقط يمكنك استخدام ملفات من تنسيق jpg كصورة المستخدم', 'order_by_sequence_off' => '', 'original_filename' => 'اسم الملف الاصلي', +'overall_indexing_progress' => '', 'owner' => 'المالك', 'ownership_changed_email' => 'تم تغيير المالك', 'ownership_changed_email_body' => 'تم تغيير المالك @@ -842,6 +848,7 @@ Parent folder: [folder_path] مستخدم: [username] URL: [url]', 'removed_workflow_email_subject' => '[sitename]: [name] - تم ازالة مسار العمل من اصدار المستند', +'removeFolderFromDropFolder' => '', 'remove_marked_files' => 'ازالة الملفات المختارة', 'repaired' => 'تم اصلاحه', 'repairing_objects' => 'تحضير المستندات والمجلدات.', @@ -913,6 +920,7 @@ URL: [url]', 'rm_default_keyword_category' => 'ازالة القسم', 'rm_document' => 'ازالة المستند', 'rm_document_category' => 'ازالة القسم', +'rm_event' => '', 'rm_file' => 'ازالة الملف', 'rm_folder' => 'ازالة المجلد', 'rm_from_clipboard' => 'ازالة من لوحة القصاصات', @@ -1319,9 +1327,11 @@ URL: [url]', 'splash_document_added' => '', 'splash_document_checkedout' => '', 'splash_document_edited' => '', +'splash_document_indexed' => '', 'splash_document_locked' => 'تم قفل المستند', 'splash_document_unlocked' => 'تم الغاء قفل المستند', 'splash_edit_attribute' => '', +'splash_edit_event' => '', 'splash_edit_group' => '', 'splash_edit_role' => '', 'splash_edit_user' => '', diff --git a/languages/bg_BG/lang.inc b/languages/bg_BG/lang.inc index 0db8f8784..6e79e657c 100644 --- a/languages/bg_BG/lang.inc +++ b/languages/bg_BG/lang.inc @@ -472,8 +472,13 @@ $text = array( 'include_content' => '', 'include_documents' => 'Включи документи', 'include_subdirectories' => 'Включи под-папки', +'indexing_tasks_in_queue' => '', 'index_converters' => 'Index document conversion', +'index_done' => '', +'index_error' => '', 'index_folder' => '', +'index_pending' => '', +'index_waiting' => '', 'individuals' => 'Личности', 'indivіduals_in_groups' => '', 'inherited' => 'наследен', @@ -668,6 +673,7 @@ $text = array( 'only_jpg_user_images' => 'Разрешени са само .jpg-изображения', 'order_by_sequence_off' => '', 'original_filename' => 'Оригинално име на файл', +'overall_indexing_progress' => '', 'owner' => 'Собственик', 'ownership_changed_email' => 'Собственикът променен', 'ownership_changed_email_body' => '', @@ -734,6 +740,7 @@ $text = array( 'removed_revispr' => '', 'removed_workflow_email_body' => '', 'removed_workflow_email_subject' => '', +'removeFolderFromDropFolder' => '', 'remove_marked_files' => '', 'repaired' => '', 'repairing_objects' => 'Поправка на папки и документи', @@ -785,6 +792,7 @@ $text = array( 'rm_default_keyword_category' => 'Премахни категория', 'rm_document' => 'Премахни документ', 'rm_document_category' => 'Премахни категория', +'rm_event' => '', 'rm_file' => 'Премахни файл', 'rm_folder' => 'Премахни папка', 'rm_from_clipboard' => 'Премахни от clipboard буфера', @@ -1184,9 +1192,11 @@ $text = array( 'splash_document_added' => '', 'splash_document_checkedout' => '', 'splash_document_edited' => '', +'splash_document_indexed' => '', 'splash_document_locked' => '', 'splash_document_unlocked' => '', 'splash_edit_attribute' => '', +'splash_edit_event' => '', 'splash_edit_group' => '', 'splash_edit_role' => '', 'splash_edit_user' => '', diff --git a/languages/ca_ES/lang.inc b/languages/ca_ES/lang.inc index e7f5e47d7..08d0e6f23 100644 --- a/languages/ca_ES/lang.inc +++ b/languages/ca_ES/lang.inc @@ -477,8 +477,13 @@ URL: [url]', 'include_content' => '', 'include_documents' => 'Incloure documents', 'include_subdirectories' => 'Incloure subdirectoris', +'indexing_tasks_in_queue' => '', 'index_converters' => '', +'index_done' => '', +'index_error' => '', 'index_folder' => 'Carpeta d\'índex', +'index_pending' => '', +'index_waiting' => '', 'individuals' => 'Individuals', 'indivіduals_in_groups' => '', 'inherited' => '', @@ -673,6 +678,7 @@ URL: [url]', 'only_jpg_user_images' => 'Només pot utilitzar imatges .jpg com imatges d\'usuari', 'order_by_sequence_off' => '', 'original_filename' => '', +'overall_indexing_progress' => '', 'owner' => 'Propietari/a', 'ownership_changed_email' => 'Propietari/a canviat', 'ownership_changed_email_body' => '', @@ -739,6 +745,7 @@ URL: [url]', 'removed_revispr' => '', 'removed_workflow_email_body' => '', 'removed_workflow_email_subject' => '', +'removeFolderFromDropFolder' => '', 'remove_marked_files' => '', 'repaired' => '', 'repairing_objects' => '', @@ -790,6 +797,7 @@ URL: [url]', 'rm_default_keyword_category' => 'Eliminar categoria', 'rm_document' => 'Eliminar document', 'rm_document_category' => '', +'rm_event' => '', 'rm_file' => 'Eliminar fitxer', 'rm_folder' => 'Eliminar carpeta', 'rm_from_clipboard' => '', @@ -1189,9 +1197,11 @@ URL: [url]', 'splash_document_added' => '', 'splash_document_checkedout' => '', 'splash_document_edited' => '', +'splash_document_indexed' => '', 'splash_document_locked' => 'Document blocat', 'splash_document_unlocked' => 'Document desblocat', 'splash_edit_attribute' => '', +'splash_edit_event' => '', 'splash_edit_group' => '', 'splash_edit_role' => '', 'splash_edit_user' => '', diff --git a/languages/cs_CZ/lang.inc b/languages/cs_CZ/lang.inc index 66612025e..329eaa525 100644 --- a/languages/cs_CZ/lang.inc +++ b/languages/cs_CZ/lang.inc @@ -548,8 +548,13 @@ URL: [url]', 'include_content' => '', 'include_documents' => 'Včetně dokumentů', 'include_subdirectories' => 'Včetně podadresářů', +'indexing_tasks_in_queue' => '', 'index_converters' => 'Index konverze dokumentu', +'index_done' => '', +'index_error' => '', 'index_folder' => 'Složka indexu', +'index_pending' => '', +'index_waiting' => '', 'individuals' => 'Jednotlivci', 'indivіduals_in_groups' => '', 'inherited' => 'Zděděno', @@ -768,6 +773,7 @@ URL: [url]', 'only_jpg_user_images' => 'Pro obrázky uživatelů je možné použít pouze obrázky .jpg', 'order_by_sequence_off' => '', 'original_filename' => 'Originální název souboru', +'overall_indexing_progress' => '', 'owner' => 'Vlastník', 'ownership_changed_email' => 'Vlastník změněn', 'ownership_changed_email_body' => 'Vlastník změněn @@ -852,6 +858,7 @@ Nadřazená složka: [folder_path] Uživatel: [username] URL: [url]', 'removed_workflow_email_subject' => '[sitename]: [name] - Odstraněn průběh práce z verze dokumentu', +'removeFolderFromDropFolder' => '', 'remove_marked_files' => 'Odstranit označené soubory', 'repaired' => 'opraveno', 'repairing_objects' => 'Opravuji dokumenty a složky.', @@ -922,6 +929,7 @@ URL: [url]', 'rm_default_keyword_category' => 'Smazat kategorii', 'rm_document' => 'Odstranit dokument', 'rm_document_category' => 'Vymazat kategorii', +'rm_event' => '', 'rm_file' => 'Odstranit soubor', 'rm_folder' => 'Odstranit složku', 'rm_from_clipboard' => 'Odstranit ze schránky', @@ -1328,9 +1336,11 @@ URL: [url]', 'splash_document_added' => 'Dokument přidán', 'splash_document_checkedout' => '', 'splash_document_edited' => 'Dokument uložen', +'splash_document_indexed' => '', 'splash_document_locked' => 'Dokument zamčen', 'splash_document_unlocked' => 'Dokument odemčen', 'splash_edit_attribute' => 'Atribut uložen', +'splash_edit_event' => '', 'splash_edit_group' => 'Skupina uložena', 'splash_edit_role' => '', 'splash_edit_user' => 'Uživatel uložen', diff --git a/languages/de_DE/lang.inc b/languages/de_DE/lang.inc index b7c1b3d5b..2c006d12c 100644 --- a/languages/de_DE/lang.inc +++ b/languages/de_DE/lang.inc @@ -19,7 +19,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// Translators: Admin (2366), dgrutsch (22) +// Translators: Admin (2376), dgrutsch (22) $text = array( '2_factor_auth' => '2-Faktor Authentifizierung', @@ -553,8 +553,13 @@ URL: [url]', 'include_content' => 'Inhalte mit exportieren', 'include_documents' => 'Dokumente miteinbeziehen', 'include_subdirectories' => 'Unterverzeichnisse miteinbeziehen', +'indexing_tasks_in_queue' => 'Indiziervorgänge in der Warteschleife', 'index_converters' => 'Index Dokumentenumwandlung', +'index_done' => 'Fertig', +'index_error' => 'Fehler', 'index_folder' => 'Indiziere Ordner', +'index_pending' => 'Vorgemerkt', +'index_waiting' => 'Warte', 'individuals' => 'Einzelpersonen', 'indivіduals_in_groups' => 'Mitglieder einer Gruppe', 'inherited' => 'geerbt', @@ -772,6 +777,7 @@ URL: [url]', 'only_jpg_user_images' => 'Es sind nur JPG-Bilder erlaubt', 'order_by_sequence_off' => 'Die Sortierung nach Folge ist in den Einstellungen ausgeschaltet. Wenn dieser Parameter wirksam sein soll, muss sie wieder eingeschaltet werden.', 'original_filename' => 'Original filename', +'overall_indexing_progress' => 'Gesamtfortschritt bei der Indizierung', 'owner' => 'Besitzer', 'ownership_changed_email' => 'Besitzer geändert', 'ownership_changed_email_body' => 'Besitzer geändert @@ -872,6 +878,7 @@ Elternordner: [folder_path] Benutzer: [username] URL: [url]', 'removed_workflow_email_subject' => '[sitename]: [name] - Workflow von Dokumentenversion', +'removeFolderFromDropFolder' => 'Ordner nach Import entfernen', 'remove_marked_files' => 'Markierte Dateien löschen', 'repaired' => 'repariert', 'repairing_objects' => 'Repariere Dokumente und Ordner.', @@ -972,6 +979,7 @@ URL: [url]', 'rm_default_keyword_category' => 'Kategorie löschen', 'rm_document' => 'Löschen', 'rm_document_category' => 'Lösche Kategorie', +'rm_event' => 'Ereignis löschen', 'rm_file' => 'Datei Löschen', 'rm_folder' => 'Löschen', 'rm_from_clipboard' => 'Aus Zwischenablage löschen', @@ -1378,9 +1386,11 @@ URL: [url]', 'splash_document_added' => 'Dokument hinzugefügt', 'splash_document_checkedout' => 'Dokument ausgecheckt', 'splash_document_edited' => 'Dokument gespeichert', +'splash_document_indexed' => 'Dokument \'[name]\' indiziert.', 'splash_document_locked' => 'Dokument gesperrt', 'splash_document_unlocked' => 'Dokumentensperre aufgehoben', 'splash_edit_attribute' => 'Attribut gespeichert', +'splash_edit_event' => 'Ereignis gespeichert', 'splash_edit_group' => 'Gruppe gespeichert', 'splash_edit_role' => 'Rolle gespeichert', 'splash_edit_user' => 'Benutzer gespeichert', diff --git a/languages/el_GR/lang.inc b/languages/el_GR/lang.inc index ad93374b1..5da788a28 100644 --- a/languages/el_GR/lang.inc +++ b/languages/el_GR/lang.inc @@ -19,7 +19,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// Translators: Admin (214) +// Translators: Admin (215) $text = array( '2_factor_auth' => '', @@ -472,8 +472,13 @@ $text = array( 'include_content' => '', 'include_documents' => '', 'include_subdirectories' => '', +'indexing_tasks_in_queue' => '', 'index_converters' => '', +'index_done' => '', +'index_error' => '', 'index_folder' => '', +'index_pending' => '', +'index_waiting' => '', 'individuals' => 'Άτομα', 'indivіduals_in_groups' => '', 'inherited' => '', @@ -606,7 +611,7 @@ $text = array( 'new' => 'Νέο', 'new_attrdef' => '', 'new_default_keywords' => '', -'new_default_keyword_category' => '', +'new_default_keyword_category' => 'Προσθήκη Κατηγορίας', 'new_document_category' => '', 'new_document_email' => 'Νέο Έγγραφο', 'new_document_email_body' => 'Νέο έγγραφο @@ -679,6 +684,7 @@ URL: [url]', 'only_jpg_user_images' => '', 'order_by_sequence_off' => '', 'original_filename' => '', +'overall_indexing_progress' => '', 'owner' => 'Ιδιοκτήτης', 'ownership_changed_email' => '', 'ownership_changed_email_body' => '', @@ -745,6 +751,7 @@ URL: [url]', 'removed_revispr' => '', 'removed_workflow_email_body' => '', 'removed_workflow_email_subject' => '', +'removeFolderFromDropFolder' => '', 'remove_marked_files' => '', 'repaired' => '', 'repairing_objects' => '', @@ -796,6 +803,7 @@ URL: [url]', 'rm_default_keyword_category' => '', 'rm_document' => 'Διαγραφή εγγράφου', 'rm_document_category' => 'Διαγραφή κατηγορίας', +'rm_event' => '', 'rm_file' => 'Διαγραφή αρχείου', 'rm_folder' => 'Διαγραφή φακέλου', 'rm_from_clipboard' => '', @@ -1195,9 +1203,11 @@ URL: [url]', 'splash_document_added' => '', 'splash_document_checkedout' => '', 'splash_document_edited' => '', +'splash_document_indexed' => '', 'splash_document_locked' => '', 'splash_document_unlocked' => '', 'splash_edit_attribute' => '', +'splash_edit_event' => '', 'splash_edit_group' => '', 'splash_edit_role' => '', 'splash_edit_user' => '', diff --git a/languages/en_GB/lang.inc b/languages/en_GB/lang.inc index aff121206..7fc2b4dc0 100644 --- a/languages/en_GB/lang.inc +++ b/languages/en_GB/lang.inc @@ -19,7 +19,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// Translators: Admin (1493), dgrutsch (9), netixw (14) +// Translators: Admin (1503), dgrutsch (9), netixw (14) $text = array( '2_factor_auth' => '2-factor authentication', @@ -553,8 +553,13 @@ URL: [url]', 'include_content' => 'Include content', 'include_documents' => 'Include documents', 'include_subdirectories' => 'Include subdirectories', +'indexing_tasks_in_queue' => 'Indexing tasks in queue', 'index_converters' => 'Index document conversion', +'index_done' => 'Done', +'index_error' => 'Error', 'index_folder' => 'Index folder', +'index_pending' => 'Pending', +'index_waiting' => 'Waiting', 'individuals' => 'Individuals', 'indivіduals_in_groups' => 'Members of a group', 'inherited' => 'inherited', @@ -773,6 +778,7 @@ URL: [url]', 'only_jpg_user_images' => 'Only .jpg-images may be used as user-images', 'order_by_sequence_off' => 'Ordering by sequence is turned off in the settings. If you want this parameter to have effect, you will have to turn it back on.', 'original_filename' => 'Original filename', +'overall_indexing_progress' => 'Overall indexing progress', 'owner' => 'Owner', 'ownership_changed_email' => 'Owner changed', 'ownership_changed_email_body' => 'Owner changed @@ -873,6 +879,7 @@ Parent folder: [folder_path] User: [username] URL: [url]', 'removed_workflow_email_subject' => '[sitename]: [name] - Removed workflow from document version', +'removeFolderFromDropFolder' => 'Remove folder after import', 'remove_marked_files' => 'Remove marked files', 'repaired' => 'repaired', 'repairing_objects' => 'Repairing documents and folders.', @@ -966,6 +973,7 @@ URL: [url]', 'rm_default_keyword_category' => 'Remove category', 'rm_document' => 'Remove document', 'rm_document_category' => 'Remove category', +'rm_event' => 'Remove event', 'rm_file' => 'Remove file', 'rm_folder' => 'Remove folder', 'rm_from_clipboard' => 'Remove from clipboard', @@ -1372,9 +1380,11 @@ URL: [url]', 'splash_document_added' => 'Document added', 'splash_document_checkedout' => 'Document checked out', 'splash_document_edited' => 'Document saved', +'splash_document_indexed' => 'Document \'[name]\' indexed.', 'splash_document_locked' => 'Document locked', 'splash_document_unlocked' => 'Document unlocked', 'splash_edit_attribute' => 'Attribute saved', +'splash_edit_event' => 'Event saved', 'splash_edit_group' => 'Group saved', 'splash_edit_role' => 'Role saved', 'splash_edit_user' => 'User saved', diff --git a/languages/es_ES/lang.inc b/languages/es_ES/lang.inc index d56dd21e4..0e3979f2d 100644 --- a/languages/es_ES/lang.inc +++ b/languages/es_ES/lang.inc @@ -19,7 +19,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// Translators: acabello (20), Admin (1008), angel (123), francisco (2), jaimem (14) +// Translators: acabello (20), Admin (1009), angel (123), francisco (2), jaimem (14) $text = array( '2_factor_auth' => '', @@ -548,8 +548,13 @@ URL: [url]', 'include_content' => '', 'include_documents' => 'Incluir documentos', 'include_subdirectories' => 'Incluir subcarpetas', +'indexing_tasks_in_queue' => '', 'index_converters' => 'Conversión de índice de documentos', +'index_done' => '', +'index_error' => '', 'index_folder' => 'Índice de carpetas', +'index_pending' => '', +'index_waiting' => '', 'individuals' => 'Individuales', 'indivіduals_in_groups' => '', 'inherited' => 'heredado', @@ -625,7 +630,7 @@ URL: [url]', 'linked_to_this_version' => '', 'link_alt_updatedocument' => 'Si desea subir archivos mayores que el tamaño máximo actualmente permitido, por favor, utilice la página de subida alternativa.', 'link_to_version' => '', -'list_access_rights' => '', +'list_access_rights' => 'Listar los derechos de acceso', 'list_contains_no_access_docs' => '', 'list_hooks' => '', 'local_file' => 'Fichero local', @@ -768,6 +773,7 @@ URL: [url]', 'only_jpg_user_images' => 'Sólo puede usar imágenes .jpg como imágenes de usuario', 'order_by_sequence_off' => 'El orden secuencial está desactivado en la configuración. Si quiere utilizar este parámetro, deberá activarlo.', 'original_filename' => 'Nombre de fichero original', +'overall_indexing_progress' => '', 'owner' => 'Propietario', 'ownership_changed_email' => 'Propietario modificado', 'ownership_changed_email_body' => 'Propietario modificado @@ -857,6 +863,7 @@ Carpeta principal: [folder_path] Usuario: [username] nURL: [url]', 'removed_workflow_email_subject' => '[sitename]: [name] - Eliminar flujo de trabajo de la versión del documento', +'removeFolderFromDropFolder' => '', 'remove_marked_files' => 'Eliminar ficheros marcados', 'repaired' => 'Reparado', 'repairing_objects' => 'Reparando documentos y carpetas.', @@ -928,6 +935,7 @@ URL: [url]', 'rm_default_keyword_category' => 'Eliminar categoría', 'rm_document' => 'Eliminar documento', 'rm_document_category' => 'Eliminar categoría', +'rm_event' => '', 'rm_file' => 'Eliminar fichero', 'rm_folder' => 'Eliminar carpeta', 'rm_from_clipboard' => 'Borrar del portapapeles', @@ -1334,9 +1342,11 @@ URL: [url]', 'splash_document_added' => 'Documento añadido', 'splash_document_checkedout' => '', 'splash_document_edited' => 'Documento guardado', +'splash_document_indexed' => '', 'splash_document_locked' => 'Documento bloqueado', 'splash_document_unlocked' => 'Documento desbloqueado', 'splash_edit_attribute' => 'Atributo guardado', +'splash_edit_event' => '', 'splash_edit_group' => 'Grupo guardado', 'splash_edit_role' => '', 'splash_edit_user' => 'Usuario guardado', diff --git a/languages/fr_FR/lang.inc b/languages/fr_FR/lang.inc index 5d7238384..8bd861f9a 100644 --- a/languages/fr_FR/lang.inc +++ b/languages/fr_FR/lang.inc @@ -19,7 +19,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// Translators: Admin (1058), jeromerobert (50), lonnnew (9), Oudiceval (171) +// Translators: Admin (1060), jeromerobert (50), lonnnew (9), Oudiceval (182) $text = array( '2_factor_auth' => 'Authentification forte', @@ -309,7 +309,7 @@ URL: [url]', 'docs_in_reception_no_access' => '', 'docs_in_revision_no_access' => '', 'document' => 'Document', -'documentcontent' => '', +'documentcontent' => 'Version de document', 'documents' => 'Documents', 'documents_checked_out_by_you' => 'Documents bloqués par vous', 'documents_in_process' => 'Documents en cours', @@ -553,8 +553,13 @@ URL: [url]', 'include_content' => '', 'include_documents' => 'Inclure les documents', 'include_subdirectories' => 'Inclure les sous-dossiers', +'indexing_tasks_in_queue' => '', 'index_converters' => 'Conversion de document Index', +'index_done' => '', +'index_error' => '', 'index_folder' => 'Dossier Index', +'index_pending' => '', +'index_waiting' => '', 'individuals' => 'Individuels', 'indivіduals_in_groups' => '', 'inherited' => 'hérité', @@ -629,8 +634,8 @@ URL: [url]', 'linked_to_document' => '', 'linked_to_this_version' => '', 'link_alt_updatedocument' => 'Pour déposer des fichiers de taille supérieure, utilisez la page d\'ajout multiple.', -'link_to_version' => '', -'list_access_rights' => '', +'link_to_version' => 'Version', +'list_access_rights' => 'Liste des droits d’accès…', 'list_contains_no_access_docs' => '', 'list_hooks' => '', 'local_file' => 'Fichier local', @@ -709,12 +714,12 @@ URL: [url]', 'new_folder' => 'Nouveau dossier', 'new_password' => 'Nouveau mot de passe', 'new_subfolder_email' => 'Nouveau dossier', -'new_subfolder_email_body' => 'Nouveau dossier -Name: [name] -Dossier parent: [folder_path] -Commentaire: [comment] -Utilisateur: [username] -URL: [url]', +'new_subfolder_email_body' => 'Nouveau dossier +Nom : [name] +Dossier parent : [folder_path] +Commentaire : [comment] +Utilisateur : [username] +URL : [url]', 'new_subfolder_email_subject' => '[sitename]: [name] - Nouveau dossier', 'new_user_image' => 'Nouvelle image', 'next_state' => 'Nouvel état', @@ -773,6 +778,7 @@ URL: [url]', 'only_jpg_user_images' => 'Images d\'utilisateur au format .jpg seulement', 'order_by_sequence_off' => 'Le tri par séquence est désactivé dans les préférences. Si vous souhaitez que ce paramètre prenne effet, vous devez l\'activer.', 'original_filename' => 'Nom de fichier original', +'overall_indexing_progress' => '', 'owner' => 'Propriétaire', 'ownership_changed_email' => 'Propriétaire modifié', 'ownership_changed_email_body' => 'Propriétaire modifié @@ -825,8 +831,14 @@ En cas de problème persistant, veuillez contacter votre administrateur.', 'quota_exceeded' => 'Votre quota de disque est dépassé de [bytes].', 'quota_is_disabled' => 'Le support des quota est actuellement désactivé dans les réglages. Affecter un quota utilisateur n\'aura pas d\'effet jusqu\'à ce qu\'il soit de nouveau activé.', 'quota_warning' => 'Votre quota d’espace disque est dépassé de [bytes]. Veuillez supprimer des documents ou d\'anciennes versions.', -'receipt_deletion_email_body' => '', -'receipt_deletion_email_subject' => '', +'receipt_deletion_email_body' => 'L’utilisateur a été retiré de la liste des destinataires +Document : [name] +Version : [version] +Dossier parent : [folder_path] +Destinataire : [recipient] +Utilisateur : [username] +URL : [url]', +'receipt_deletion_email_subject' => '[sitename] : [name] - Destinataire supprimé', 'receipt_log' => '', 'receipt_request_email_body' => '', 'receipt_request_email_subject' => '', @@ -859,6 +871,7 @@ Répertoire: [folder_path] Utilisateur: [username] URL: [url]', 'removed_workflow_email_subject' => '', +'removeFolderFromDropFolder' => '', 'remove_marked_files' => 'Supprimer les fichiers sélectionnés', 'repaired' => 'réparé', 'repairing_objects' => 'Réparation des documents et des dossiers.', @@ -917,6 +930,7 @@ URL: [url]', 'rm_default_keyword_category' => 'Supprimer la catégorie', 'rm_document' => 'Supprimer le document', 'rm_document_category' => 'Supprimer la catégorie', +'rm_event' => 'Supprimer l’événement', 'rm_file' => 'Supprimer le fichier', 'rm_folder' => 'Supprimer le dossier', 'rm_from_clipboard' => 'Supprimer le dossier du presse-papiers', @@ -1044,8 +1058,8 @@ URL: [url]', 'settings_dbUser' => 'Nom d\'utilisateur', 'settings_dbUser_desc' => 'Le nom d\'utilisateur pour l\'accès à votre base de données entré pendant le processus d\'installation. Ne pas modifier le champ sauf si vraiment nécessaire, par exemple pour le transfert de la base de données vers un nouvel hébergement.', 'settings_dbVersion' => 'Schéma de base de données trop ancien', -'settings_defaultAccessDocs' => '', -'settings_defaultAccessDocs_desc' => '', +'settings_defaultAccessDocs' => 'Accès par défaut des nouveaux documents', +'settings_defaultAccessDocs_desc' => 'Lors de la création d’un nouveau document, ce droit d’accès sera appliqué par défaut.', 'settings_defaultSearchMethod' => 'Méthode de recherche par défaut', 'settings_defaultSearchMethod_desc' => 'Méthode de recherche par défaut, lorsque la recherche est exécutée depuis le moteur de recherche du menu principal', 'settings_defaultSearchMethod_valdatabase' => 'base de données', @@ -1118,8 +1132,8 @@ URL: [url]', 'settings_enableThemeSelector_desc' => 'Activer/désactiver le sélecteur de thème sur la page de connexion.', 'settings_enableUpdateReceipt' => '', 'settings_enableUpdateReceipt_desc' => '', -'settings_enableUpdateRevApp' => '', -'settings_enableUpdateRevApp_desc' => '', +'settings_enableUpdateRevApp' => 'Autorise la modification de révisions et approbations existantes', +'settings_enableUpdateRevApp_desc' => 'A activer si l\'utilisateur qui a fait la révision/approbations peut changer sa position alors que l\'étape actuelle du processus n\'est pas terminée', 'settings_enableUserImage' => 'Activer image utilisateurs', 'settings_enableUserImage_desc' => 'Activer les images utilisateurs', 'settings_enableUsersView' => 'Activer Vue des Utilisateurs', @@ -1156,7 +1170,7 @@ URL: [url]', 'settings_initialDocumentStatus_draft' => 'Brouillon', 'settings_initialDocumentStatus_released' => 'publié', 'settings_installADOdb' => 'Installer ADOdb', -'settings_install_disabled' => 'Le fichier ENABLE_INSTALL_TOOL a été supprimé. ous pouvez maintenant vous connecter à SeedDMS et poursuivre la configuration.', +'settings_install_disabled' => 'Le fichier ENABLE_INSTALL_TOOL a été supprimé. Vous pouvez maintenant vous connecter à SeedDMS et poursuivre la configuration.', 'settings_install_pear_package_log' => 'Installer le paquet Pear \'Log\'', 'settings_install_pear_package_webdav' => 'Installer le paquet Pear \'HTTP_WebDAV_Server\', si vous avez l\'intention d\'utiliser l\'interface webdav', 'settings_install_success' => 'L\'installation est terminée avec succès', @@ -1221,7 +1235,7 @@ URL: [url]', 'settings_printDisclaimer_desc' => 'Si activé, le message d’avertissement sera affiché en bas de chaque page.', 'settings_quota' => 'Quota de l\'utilisateur', 'settings_quota_desc' => 'Le maximum de bytes qu\'un utilisateur peut utiliser sur le disque. Définir à 0 pour un espace illimité. Cette valeur peut être outrepasser pour chaque utilisation dans son profile.', -'settings_removeFromDropFolder' => 'Supprimer le fichier du dossier de dépôt après un upload résussi', +'settings_removeFromDropFolder' => 'Supprimer le fichier du dossier de dépôt après un chargement réussi', 'settings_removeFromDropFolder_desc' => 'Activez ceci si un fichier pris du dossier de dépôt doit être supprimé après un upload réussi.', 'settings_restricted' => 'Accès restreint', 'settings_restricted_desc' => 'Autoriser les utilisateurs à se connecter seulement s\'ils ont une entrée dans la BD locale (independamment d\'une authentification réussie avec LDAP)', @@ -1316,9 +1330,11 @@ URL: [url]', 'splash_document_added' => 'Document ajouté', 'splash_document_checkedout' => 'Document bloqué', 'splash_document_edited' => 'Document sauvegardé', +'splash_document_indexed' => '', 'splash_document_locked' => 'Document vérouillé', 'splash_document_unlocked' => 'Document déverrouillé', 'splash_edit_attribute' => 'Attribut modifié', +'splash_edit_event' => '', 'splash_edit_group' => 'Groupe sauvé', 'splash_edit_role' => '', 'splash_edit_user' => 'Utilisateur modifié', diff --git a/languages/hr_HR/lang.inc b/languages/hr_HR/lang.inc index c7ca21f5e..00f0a0250 100644 --- a/languages/hr_HR/lang.inc +++ b/languages/hr_HR/lang.inc @@ -19,7 +19,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// Translators: Admin (1191), marbanas (16) +// Translators: Admin (1195), marbanas (16) $text = array( '2_factor_auth' => '', @@ -553,8 +553,13 @@ Internet poveznica: [url]', 'include_content' => 'Uključi sadržaj', 'include_documents' => 'Sadrži dokumente', 'include_subdirectories' => 'Sadrži podmape', +'indexing_tasks_in_queue' => '', 'index_converters' => 'Pretvorba indeksa dokumenta', +'index_done' => '', +'index_error' => '', 'index_folder' => 'Mapa indeksa', +'index_pending' => '', +'index_waiting' => '', 'individuals' => 'Pojedinci', 'indivіduals_in_groups' => '', 'inherited' => 'naslijeđeno', @@ -772,6 +777,7 @@ Internet poveznica: [url]', 'only_jpg_user_images' => 'Kao korisničke slike mogu se koristiti samo .jpg slike', 'order_by_sequence_off' => 'Sortiranje po sekvencei ne isključeno u postavkama. Ako želite da ovaj parametar ima utjecaja, morat ćete ga ponovno uključiti.', 'original_filename' => 'Izvorni naziv datoteke', +'overall_indexing_progress' => '', 'owner' => 'Vlasnik', 'ownership_changed_email' => 'Promijenjen vlasnik', 'ownership_changed_email_body' => 'Promijenjen vlasnik @@ -861,6 +867,7 @@ Glavna mapa: [folder_path] Korisnik: [username] Internet poveznica: [url]', 'removed_workflow_email_subject' => '[sitename]: [name] - Uklonjeni tok rada iz ove verzije dokumenta', +'removeFolderFromDropFolder' => '', 'remove_marked_files' => 'Ukloni označene datoteke', 'repaired' => 'popravljeno', 'repairing_objects' => 'Popravljanje dokumenata ili mapa.', @@ -949,6 +956,7 @@ Internet poveznica: [url]', 'rm_default_keyword_category' => 'Uklonite kategoriju', 'rm_document' => 'Ukloni dokument', 'rm_document_category' => 'Uklonite kategoriju', +'rm_event' => '', 'rm_file' => 'Uklonite datoteku', 'rm_folder' => 'Uklonite mapu', 'rm_from_clipboard' => 'Uklonite iz međuspremnika', @@ -1042,7 +1050,7 @@ Internet poveznica: [url]', 'settings_Authentication' => 'Postavke autentifikacije', 'settings_autoLoginUser' => 'Automatska prijava', 'settings_autoLoginUser_desc' => 'Koristite ovaj korisnički ID za pristup ukoliko korisnik već nije prijavljen. Takav pristup neće otvoriti sesiju.', -'settings_available_languages' => '', +'settings_available_languages' => 'Dostupni jezici', 'settings_available_languages_desc' => '', 'settings_backupDir' => 'Mapa za sigurnosnu kopiju', 'settings_backupDir_desc' => 'Mapa gdje alat za sigurnosne kopije sprema podatke. Ako ova mapa nije postavljena ili joj se ne može pristupiti, tada se sigurnosne kopije spremaju u mapu sadržaja.', @@ -1060,7 +1068,7 @@ Internet poveznica: [url]', 'settings_contentDir_desc' => 'Gdje se spremaju učitane datoteke (najbolje da odaberete mapu koja nije dostupna kroz vaš web-server)', 'settings_contentOffsetDir' => 'Offset mapa sadržaja', 'settings_contentOffsetDir_desc' => 'Za zaobilaželje ograničenja unutar datotečnog sustava, nova struktura mapa je a new directory structure je zasnovana i nalazi se unutar mape sadržaja. Ovo zahtjeva baznu mapu od koje se kreće. Uobičajeno da se ostavlja zadana postavka, 1048576, ali može biti bilo koji niz koji se već ne nalazi unutar mape sadržaja', -'settings_convertToPdf' => '', +'settings_convertToPdf' => 'Pretvori dokument u PDF format za brzi prikaz', 'settings_convertToPdf_desc' => '', 'settings_cookieLifetime' => 'Životni vijek kolačića', 'settings_cookieLifetime_desc' => 'Životni vijek kolačića u sekundama. Ako je postavljeno na 0, kolačić će biti uklonjen kada se zatvori pretraživač.', @@ -1222,7 +1230,7 @@ Internet poveznica: [url]', 'settings_maxExecutionTime_desc' => 'Ovo postavlja maksimalno vrijeme u sekundama u kojem je skripti dopušteno da se pokrene prije nego se prekine rasčlanjivanjem', 'settings_maxRecursiveCount' => 'Max. broj rekurzivnog dokumenta/mape', 'settings_maxRecursiveCount_desc' => 'To je maksimalni broj dokumenata ili mapa koji će biti označen pristupnim pravima, pri rekurzivnom brojanju objekata. Ako se taj broj premaši, broj dokumenata i mapa u pregledu mape će biti procjenjen.', -'settings_maxSizeForFullText' => '', +'settings_maxSizeForFullText' => 'Maksimalna veličina dokumenta za instant indeksiranje', 'settings_maxSizeForFullText_desc' => '', 'settings_more_settings' => 'Konfiguriraj više postavki. Zadana prijava: admin/admin', 'settings_notfound' => 'Nije pronađeno', @@ -1270,7 +1278,7 @@ Internet poveznica: [url]', 'settings_rootFolderID_desc' => 'ID root mape (većinom ne treba mijenjati)', 'settings_SaveError' => 'Greška pri spremanju datoteke konfiguracije', 'settings_Server' => 'Postavke servera', -'settings_showFullPreview' => '', +'settings_showFullPreview' => 'Prikaži cijeli dokument', 'settings_showFullPreview_desc' => '', 'settings_showMissingTranslations' => 'Prikaži prijevode koji nedostaju', 'settings_showMissingTranslations_desc' => 'Navedi sve prijevode koji nedostaju na stranici na dnu stranice. Prijavljeni korisnik će moći podnijeti prijedlog za prijevode koji nedostaju koji će biti pohranjen u csv datoteku. Ne uključujte ovu funkciju ako ste u proizvodnoj okolini!', @@ -1355,9 +1363,11 @@ Internet poveznica: [url]', 'splash_document_added' => 'Dokument dodan', 'splash_document_checkedout' => 'Dokument odjavljen', 'splash_document_edited' => 'Dokument pohranjen', +'splash_document_indexed' => '', 'splash_document_locked' => 'Dokument zaključan', 'splash_document_unlocked' => 'Dokument otključan', 'splash_edit_attribute' => 'Atribut pohranjen', +'splash_edit_event' => '', 'splash_edit_group' => 'Groupa pohranjena', 'splash_edit_role' => '', 'splash_edit_user' => 'Korisnik pohranjen', diff --git a/languages/hu_HU/lang.inc b/languages/hu_HU/lang.inc index 9ae96862e..7225b6564 100644 --- a/languages/hu_HU/lang.inc +++ b/languages/hu_HU/lang.inc @@ -548,8 +548,13 @@ URL: [url]', 'include_content' => '', 'include_documents' => 'Tartalmazó dokumentumok', 'include_subdirectories' => 'Tartalmazó alkönyvtárak', +'indexing_tasks_in_queue' => '', 'index_converters' => 'Index dokumentum konverzió', +'index_done' => '', +'index_error' => '', 'index_folder' => 'Mappa indexelése', +'index_pending' => '', +'index_waiting' => '', 'individuals' => 'Egyedek', 'indivіduals_in_groups' => '', 'inherited' => 'örökölt', @@ -768,6 +773,7 @@ URL: [url]', 'only_jpg_user_images' => 'Felhasználói képként csak .jpg állományok adhatók meg', 'order_by_sequence_off' => '', 'original_filename' => 'Eredeti fájlnév', +'overall_indexing_progress' => '', 'owner' => 'Tulajdonos', 'ownership_changed_email' => 'Tulajdonos megváltozott', 'ownership_changed_email_body' => 'Tulajdonos megváltozott @@ -857,6 +863,7 @@ Szülő mappa: [folder_path] Felhasználó: [username] URL: [url]', 'removed_workflow_email_subject' => '[sitename]: [name] - Dokumentum változatból eltávolított munkafolyamat', +'removeFolderFromDropFolder' => '', 'remove_marked_files' => 'Megjelölt állományok eltávolítása', 'repaired' => 'javított', 'repairing_objects' => 'Dokumentumok és mappák helyreállítása', @@ -928,6 +935,7 @@ URL: [url]', 'rm_default_keyword_category' => 'Kategória eltávolítása', 'rm_document' => 'Dokumentum eltávolítása', 'rm_document_category' => 'Kategória eltávolítása', +'rm_event' => '', 'rm_file' => 'Állomány eltávolítása', 'rm_folder' => 'Könyvtár eltávolítása', 'rm_from_clipboard' => 'Eltávolítás a vágólapról', @@ -1333,9 +1341,11 @@ URL: [url]', 'splash_document_added' => '', 'splash_document_checkedout' => '', 'splash_document_edited' => 'Dokumentum elmentve', +'splash_document_indexed' => '', 'splash_document_locked' => 'Dokumentum zárolva', 'splash_document_unlocked' => 'Dokumentum zárolás feloldva', 'splash_edit_attribute' => 'Jellemző mentve', +'splash_edit_event' => '', 'splash_edit_group' => 'Csoport mentve', 'splash_edit_role' => '', 'splash_edit_user' => 'Felhasználó mentve', diff --git a/languages/it_IT/lang.inc b/languages/it_IT/lang.inc index 382559be4..59d918fba 100644 --- a/languages/it_IT/lang.inc +++ b/languages/it_IT/lang.inc @@ -19,7 +19,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// Translators: Admin (1537), rickr (144), s.pnt (26) +// Translators: Admin (1538), rickr (144), s.pnt (26) $text = array( '2_factor_auth' => 'Autorizzazione a due fattori', @@ -554,8 +554,13 @@ URL: [url]', 'include_content' => 'Includi contenuto', 'include_documents' => 'Includi documenti', 'include_subdirectories' => 'Includi sottocartelle', +'indexing_tasks_in_queue' => '', 'index_converters' => 'Indice di conversione documenti', +'index_done' => '', +'index_error' => '', 'index_folder' => 'Indicizza cartella', +'index_pending' => '', +'index_waiting' => '', 'individuals' => 'Singoli', 'indivіduals_in_groups' => 'I membri de la gruppo', 'inherited' => 'ereditato', @@ -774,6 +779,7 @@ URL: [url]', 'only_jpg_user_images' => 'Possono essere utilizzate solo immagini di tipo jpeg', 'order_by_sequence_off' => 'Ordina in sequenza disabilitato', 'original_filename' => 'Nome file originale', +'overall_indexing_progress' => '', 'owner' => 'Proprietario', 'ownership_changed_email' => 'Proprietario cambiato', 'ownership_changed_email_body' => 'Cambio di proprietario @@ -868,6 +874,7 @@ Cartella: [folder_path] Utente: [username] URL: [url]', 'removed_workflow_email_subject' => '[sitename]: [name] - Flusso di lavoro rimosso dalla versione del documento', +'removeFolderFromDropFolder' => '', 'remove_marked_files' => 'Rimuovi i files contrassegnati', 'repaired' => 'riparato', 'repairing_objects' => 'Riparazione documenti e cartelle in corso...', @@ -961,6 +968,7 @@ URL: [url]', 'rm_default_keyword_category' => 'Rimuovi categoria', 'rm_document' => 'Rimuovi documento', 'rm_document_category' => 'Rimuovi categoria', +'rm_event' => '', 'rm_file' => 'Rimuovi file', 'rm_folder' => 'Rimuovi cartella', 'rm_from_clipboard' => 'Rimuovi dalla clipboard', @@ -1054,7 +1062,7 @@ URL: [url]', 'settings_Authentication' => 'Impostazioni di Autenticazione', 'settings_autoLoginUser' => 'Login automatico', 'settings_autoLoginUser_desc' => 'Utilizzare questo ID utente per l\'accesso se l\'utente non è già connesso. Questo tipo di accesso non creerà una sessione.', -'settings_available_languages' => '', +'settings_available_languages' => 'Lingue disponibili', 'settings_available_languages_desc' => '', 'settings_backupDir' => 'Directory di backup', 'settings_backupDir_desc' => 'Directory in cui lo strumento di backup salva i backup. Se questa directory non è impostato o non è possibile accedervi, quindi i backup vengono salvati nella directory dei contenuti.', @@ -1367,9 +1375,11 @@ URL: [url]', 'splash_document_added' => 'Documento aggiunto', 'splash_document_checkedout' => 'Documento approvato', 'splash_document_edited' => 'Documento modificato', +'splash_document_indexed' => '', 'splash_document_locked' => 'Documento bloccato', 'splash_document_unlocked' => 'Documento sbloccato', 'splash_edit_attribute' => 'Attributo modificato', +'splash_edit_event' => '', 'splash_edit_group' => 'Gruppo modificato', 'splash_edit_role' => 'Ruolo memorizzata', 'splash_edit_user' => 'Utente modificato', diff --git a/languages/ko_KR/lang.inc b/languages/ko_KR/lang.inc index f8ae12238..4a6b5c914 100644 --- a/languages/ko_KR/lang.inc +++ b/languages/ko_KR/lang.inc @@ -553,8 +553,13 @@ URL: [url]', 'include_content' => '내용을 포함', 'include_documents' => '문서 포함', 'include_subdirectories' => '서브 디렉토리를 포함', +'indexing_tasks_in_queue' => '', 'index_converters' => '인덱스 문서 변환', +'index_done' => '', +'index_error' => '', 'index_folder' => '인덱스 폴더', +'index_pending' => '', +'index_waiting' => '', 'individuals' => '개인', 'indivіduals_in_groups' => '개별 그룹', 'inherited' => '상속', @@ -773,6 +778,7 @@ URL : [url]', 'only_jpg_user_images' => '.JPG - 이미지만 사용자가 이미지로 사용할 수 있습니다', 'order_by_sequence_off' => '순서에 의한 정렬 설정이 켜져 있습니다. 이 매개 변수를 사용하고 싶은 경우 이것을 활성화 해야 합니다.', 'original_filename' => '원래본 파일명', +'overall_indexing_progress' => '', 'owner' => '소유자', 'ownership_changed_email' => '소유자 변경', 'ownership_changed_email_body' => '소유자 변경 @@ -854,6 +860,7 @@ URL : [url]', 사용자: [username] URL: [url]', 'removed_workflow_email_subject' => '[sitename] : [name] - 문서 버전에서 제거 된 워크플로우', +'removeFolderFromDropFolder' => '', 'remove_marked_files' => '마크 파일을 제거', 'repaired' => '복구', 'repairing_objects' => '문서 및 폴더 복구', @@ -942,6 +949,7 @@ URL: [url]', 'rm_default_keyword_category' => '범주 제거', 'rm_document' => '문서 제거', 'rm_document_category' => '카테고리 제거', +'rm_event' => '', 'rm_file' => '파일 삭제', 'rm_folder' => '폴더 제거', 'rm_from_clipboard' => '클립 보드에서 제거', @@ -1348,9 +1356,11 @@ URL : [url]', 'splash_document_added' => '문서를 추가', 'splash_document_checkedout' => '문서 체크아웃', 'splash_document_edited' => '문서 저장', +'splash_document_indexed' => '', 'splash_document_locked' => '문서 잠금', 'splash_document_unlocked' => '문서 잠금 해제', 'splash_edit_attribute' => '속성 저장', +'splash_edit_event' => '', 'splash_edit_group' => '그룹 저장', 'splash_edit_role' => '', 'splash_edit_user' => '사용자 저장', diff --git a/languages/nl_NL/lang.inc b/languages/nl_NL/lang.inc index 139e9a822..494e9ec49 100644 --- a/languages/nl_NL/lang.inc +++ b/languages/nl_NL/lang.inc @@ -546,8 +546,13 @@ URL: [url]', 'include_content' => 'inclusief inhoud', 'include_documents' => 'Inclusief documenten', 'include_subdirectories' => 'Inclusief submappen', +'indexing_tasks_in_queue' => '', 'index_converters' => 'Index document conversie', +'index_done' => '', +'index_error' => '', 'index_folder' => 'Inhoud', +'index_pending' => '', +'index_waiting' => '', 'individuals' => 'Individuen', 'indivіduals_in_groups' => 'Individuen in groepen', 'inherited' => 'overgeerfd', @@ -765,6 +770,7 @@ URL: [url]', 'only_jpg_user_images' => 'U mag alleen .jpg afbeeldingen gebruiken als gebruikersafbeeldingen.', 'order_by_sequence_off' => 'Volgorde uit', 'original_filename' => 'Originele bestandsnaam', +'overall_indexing_progress' => '', 'owner' => 'Eigenaar', 'ownership_changed_email' => 'Eigenaar gewijzigd', 'ownership_changed_email_body' => 'Eigenaar gewijzigd @@ -859,6 +865,7 @@ Bovenliggende map: [folder_path] Gebruiker: [username] URL: [url]', 'removed_workflow_email_subject' => '[sitename]: [name] - Workflow verwijderd van document versie', +'removeFolderFromDropFolder' => '', 'remove_marked_files' => 'Geselecteerde bestanden zijn verwijderd', 'repaired' => 'Gerepareerd', 'repairing_objects' => 'Documenten en mappen repareren.', @@ -951,6 +958,7 @@ URL: [url]', 'rm_default_keyword_category' => 'Verwijder Categorie', 'rm_document' => 'Verwijder Document', 'rm_document_category' => 'Verwijder categorie', +'rm_event' => '', 'rm_file' => 'Verwijder bestand', 'rm_folder' => 'Verwijder map', 'rm_from_clipboard' => 'Verwijder van klembord', @@ -1361,9 +1369,11 @@ URL: [url]', 'splash_document_added' => 'Nieuw document toegevoegd', 'splash_document_checkedout' => 'Document in gebruik genomen', 'splash_document_edited' => 'Document opgeslagen', +'splash_document_indexed' => '', 'splash_document_locked' => 'Document vergrendeld', 'splash_document_unlocked' => 'Document ontgrendeld', 'splash_edit_attribute' => 'Attribuut opgeslagen', +'splash_edit_event' => '', 'splash_edit_group' => 'Groep opgeslagen', 'splash_edit_role' => 'Rol opgeslagen', 'splash_edit_user' => 'Gebruiker opgeslagen', diff --git a/languages/pl_PL/lang.inc b/languages/pl_PL/lang.inc index 1fd9926d9..29ebaf51f 100644 --- a/languages/pl_PL/lang.inc +++ b/languages/pl_PL/lang.inc @@ -19,7 +19,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// Translators: Admin (747), netixw (84), romi (93), uGn (112) +// Translators: Admin (752), netixw (84), romi (93), uGn (112) $text = array( '2_factor_auth' => '', @@ -541,8 +541,13 @@ URL: [url]', 'include_content' => '', 'include_documents' => 'Uwzględnij dokumenty', 'include_subdirectories' => 'Uwzględnij podkatalogi', +'indexing_tasks_in_queue' => '', 'index_converters' => 'Konwersja indeksu dokumentów', +'index_done' => '', +'index_error' => '', 'index_folder' => 'Indeksuj folder', +'index_pending' => '', +'index_waiting' => '', 'individuals' => 'Indywidualni', 'indivіduals_in_groups' => '', 'inherited' => 'dziedziczony', @@ -761,6 +766,7 @@ URL: [url]', 'only_jpg_user_images' => 'Wyłącznie pliki typu .jpg mogą być użyte jako obrazy użytkowników', 'order_by_sequence_off' => '', 'original_filename' => 'Oryginalna nazwa pliku', +'overall_indexing_progress' => '', 'owner' => 'Właściciel', 'ownership_changed_email' => 'Właściciel zmieniony', 'ownership_changed_email_body' => 'Zmiana właściciela @@ -850,6 +856,7 @@ Folder nadrzędny: [folder_path] Użytkownik: [username] URL: [url]', 'removed_workflow_email_subject' => '[sitename]: [name] - Usunięty workflow z wersji dokumentu', +'removeFolderFromDropFolder' => '', 'remove_marked_files' => 'Usuń zaznaczone pliki', 'repaired' => 'naprawiony', 'repairing_objects' => 'Naprawa dokumentów i katalogów.', @@ -907,6 +914,7 @@ URL: [url]', 'rm_default_keyword_category' => 'Usuń kategorię', 'rm_document' => 'Usuń dokument', 'rm_document_category' => 'Usuń kategorię', +'rm_event' => '', 'rm_file' => 'Usuń plik', 'rm_folder' => 'Usuń folder', 'rm_from_clipboard' => 'Usuń ze schowka', @@ -1000,7 +1008,7 @@ URL: [url]', 'settings_Authentication' => 'Ustawienia uwierzytelniania', 'settings_autoLoginUser' => '', 'settings_autoLoginUser_desc' => '', -'settings_available_languages' => '', +'settings_available_languages' => 'Dostępne języki', 'settings_available_languages_desc' => '', 'settings_backupDir' => '', 'settings_backupDir_desc' => '', @@ -1085,7 +1093,7 @@ URL: [url]', 'settings_enableGuestAutoLogin_desc' => '', 'settings_enableGuestLogin' => 'Pozwól na logowanie gościa', 'settings_enableGuestLogin_desc' => 'Jeśli chcesz dowolnej osobie zalogować się jako gość, zaznacz tę opcję. Uwaga: logowanie gościa powinno być używane wyłącznie w zaufanym środowisku.', -'settings_enableHelp' => '', +'settings_enableHelp' => 'Włącz pomoc', 'settings_enableHelp_desc' => '', 'settings_enableLanguageSelector' => 'Włącz wybór języka', 'settings_enableLanguageSelector_desc' => 'Pokaż selektor języka dla interfejsu użytkownika po zalogowaniu To nie ma wpływu na wybór języka na stronie logowania.', @@ -1210,9 +1218,9 @@ URL: [url]', 'settings_php_version' => 'Wersja PHP', 'settings_presetExpirationDate' => '', 'settings_presetExpirationDate_desc' => '', -'settings_previewWidthDetail' => '', -'settings_previewWidthDetail_desc' => '', -'settings_previewWidthList' => '', +'settings_previewWidthDetail' => 'Szerokość obrazka podglądu (szczegóły)', +'settings_previewWidthDetail_desc' => 'Szerokość obrazka podglądu na stronie szczegółów', +'settings_previewWidthList' => 'Szerokość obrazka podglądu (lista)', 'settings_previewWidthList_desc' => 'Szerokość podglądu obrazu pokazanego na liście', 'settings_printDisclaimer' => 'Wyświetlaj Zrzeczenie się', 'settings_printDisclaimer_desc' => 'Zaznaczenie tej opcji spowoduje, że na dole strony będzie wyświetlany komunikat zrzeczenia się zawarty w pliku lang.inc.', @@ -1313,9 +1321,11 @@ URL: [url]', 'splash_document_added' => '', 'splash_document_checkedout' => '', 'splash_document_edited' => 'Dokument został zapisany', +'splash_document_indexed' => '', 'splash_document_locked' => 'Dokument zablokowany', 'splash_document_unlocked' => 'Odblokowano dokument', 'splash_edit_attribute' => 'Zapisano atrybuty', +'splash_edit_event' => '', 'splash_edit_group' => 'Grupa zapisana', 'splash_edit_role' => '', 'splash_edit_user' => 'Zapisano użytkownika', diff --git a/languages/pt_BR/lang.inc b/languages/pt_BR/lang.inc index 2b4ff6e33..1191f27e5 100644 --- a/languages/pt_BR/lang.inc +++ b/languages/pt_BR/lang.inc @@ -547,8 +547,13 @@ URL: [url]', 'include_content' => '', 'include_documents' => 'Include documents', 'include_subdirectories' => 'Include subdirectories', +'indexing_tasks_in_queue' => '', 'index_converters' => 'Índice de conversão de documentos', +'index_done' => '', +'index_error' => '', 'index_folder' => 'Pasta Raiz', +'index_pending' => '', +'index_waiting' => '', 'individuals' => 'Individuals', 'indivіduals_in_groups' => '', 'inherited' => 'herdado', @@ -766,6 +771,7 @@ URL: [url]', 'only_jpg_user_images' => 'Somente imagens jpg podem ser utilizadas como avatar', 'order_by_sequence_off' => '', 'original_filename' => 'Arquivo original', +'overall_indexing_progress' => '', 'owner' => 'Proprietário', 'ownership_changed_email' => 'O proprietário mudou', 'ownership_changed_email_body' => 'Proprietário mudou @@ -855,6 +861,7 @@ Pasta mãe: [folder_path] Usuário: [username] URL: [url]', 'removed_workflow_email_subject' => '[sitename]: [name] - Fluxo de trabalho removido da versão do documento', +'removeFolderFromDropFolder' => '', 'remove_marked_files' => 'Remover arquivos marcados', 'repaired' => 'reparado', 'repairing_objects' => 'Reparando documentos e pastas', @@ -925,6 +932,7 @@ URL: [url]', 'rm_default_keyword_category' => 'Apague esta categoria', 'rm_document' => 'Remove documento', 'rm_document_category' => 'Remover categoria', +'rm_event' => '', 'rm_file' => 'Remove file', 'rm_folder' => 'Remove pasta', 'rm_from_clipboard' => 'Remover da área de transferência', @@ -1331,9 +1339,11 @@ URL: [url]', 'splash_document_added' => 'Documento inserido', 'splash_document_checkedout' => '', 'splash_document_edited' => 'Documento salvo', +'splash_document_indexed' => '', 'splash_document_locked' => 'Documento bloqueado', 'splash_document_unlocked' => 'Documento desbloqueado', 'splash_edit_attribute' => 'Atributo salvo', +'splash_edit_event' => '', 'splash_edit_group' => 'Grupo salvo', 'splash_edit_role' => '', 'splash_edit_user' => 'Usuário salvo', diff --git a/languages/ro_RO/lang.inc b/languages/ro_RO/lang.inc index 0eed5ad8e..830d10f4c 100644 --- a/languages/ro_RO/lang.inc +++ b/languages/ro_RO/lang.inc @@ -553,8 +553,13 @@ URL: [url]', 'include_content' => '', 'include_documents' => 'Include documente', 'include_subdirectories' => 'Include subfoldere', +'indexing_tasks_in_queue' => '', 'index_converters' => 'Indexare conversie documente', +'index_done' => '', +'index_error' => '', 'index_folder' => 'Index folder', +'index_pending' => '', +'index_waiting' => '', 'individuals' => 'Individuals', 'indivіduals_in_groups' => '', 'inherited' => 'moștenit', @@ -773,6 +778,7 @@ URL: [url]', 'only_jpg_user_images' => 'Doar imagini .jpg pot fi utilizate ca imagine-utilizator', 'order_by_sequence_off' => 'Ordonarea dupa secventa este dezactivata in setari. Daca doriti acest parametru sa aiba efect, va trebui sa-l reactivati.', 'original_filename' => 'Nume de fișier original', +'overall_indexing_progress' => '', 'owner' => 'Proprietar', 'ownership_changed_email' => 'Proprietar schimbat', 'ownership_changed_email_body' => 'Proprietar schimbat @@ -862,6 +868,7 @@ Folder parinte: [folder_path] Utilizator: [username] URL: [url]', 'removed_workflow_email_subject' => '[sitename]: [name] - Workflow eliminat din versiunea documentului', +'removeFolderFromDropFolder' => '', 'remove_marked_files' => 'Eliminați fișierele marcate', 'repaired' => 'reparat', 'repairing_objects' => 'Reparare documente și foldere.', @@ -950,6 +957,7 @@ URL: [url]', 'rm_default_keyword_category' => 'Eliminați categorie', 'rm_document' => 'Eliminați document', 'rm_document_category' => 'Eliminați categorie', +'rm_event' => '', 'rm_file' => 'Eliminați fisier', 'rm_folder' => 'Eliminați folder', 'rm_from_clipboard' => 'Eliminați din clipboard', @@ -1356,9 +1364,11 @@ URL: [url]', 'splash_document_added' => 'Document adăugat', 'splash_document_checkedout' => 'Document verificat', 'splash_document_edited' => 'Document salvat', +'splash_document_indexed' => '', 'splash_document_locked' => 'Document blocat', 'splash_document_unlocked' => 'Document deblocat', 'splash_edit_attribute' => 'Atribut salvat', +'splash_edit_event' => '', 'splash_edit_group' => 'Grup salvat', 'splash_edit_role' => '', 'splash_edit_user' => 'Utilizator salvat', diff --git a/languages/ru_RU/lang.inc b/languages/ru_RU/lang.inc index e85f6448e..af73a6d70 100644 --- a/languages/ru_RU/lang.inc +++ b/languages/ru_RU/lang.inc @@ -553,8 +553,13 @@ URL: [url]', 'include_content' => 'Включая содержимое', 'include_documents' => 'Включая документы', 'include_subdirectories' => 'Включая подкаталоги', +'indexing_tasks_in_queue' => '', 'index_converters' => 'Индексирование документов', +'index_done' => '', +'index_error' => '', 'index_folder' => 'Полнотекстовый индекс', +'index_pending' => '', +'index_waiting' => '', 'individuals' => 'Пользователи', 'indivіduals_in_groups' => 'Пользователи группы', 'inherited' => 'унаследованный', @@ -772,6 +777,7 @@ URL: [url]', 'only_jpg_user_images' => 'Разрешены только .jpg-изображения', 'order_by_sequence_off' => 'Сортировка последовательности выключена в настройках. Если вы хотите применить этот эффект, вам необходимо его включить', 'original_filename' => 'Исходное имя файла', +'overall_indexing_progress' => '', 'owner' => 'Владелец', 'ownership_changed_email' => 'Владелец изменён', 'ownership_changed_email_body' => 'Изменён владелец @@ -864,6 +870,7 @@ URL: [url]', Пользователь: [username] URL: [url]', 'removed_workflow_email_subject' => '[sitename]: удалён процесс из версии документа «[name]»', +'removeFolderFromDropFolder' => '', 'remove_marked_files' => 'Удалить выбранные файлы', 'repaired' => 'исправлено', 'repairing_objects' => 'Восстановление каталогов и документов', @@ -957,6 +964,7 @@ URL: [url]', 'rm_default_keyword_category' => 'Удалить метку', 'rm_document' => 'Удалить документ', 'rm_document_category' => 'Удалить категорию', +'rm_event' => '', 'rm_file' => 'Удалить файл', 'rm_folder' => 'Удалить каталог', 'rm_from_clipboard' => 'Удалить из буфера обмена', @@ -1363,9 +1371,11 @@ URL: [url]', 'splash_document_added' => 'Добавлен документ', 'splash_document_checkedout' => 'Документ отправлен на обработку', 'splash_document_edited' => 'Документ сохранён', +'splash_document_indexed' => '', 'splash_document_locked' => 'Документ заблокирован', 'splash_document_unlocked' => 'Документ разблокирован', 'splash_edit_attribute' => 'Атрибут сохранён', +'splash_edit_event' => '', 'splash_edit_group' => 'Группа сохранена', 'splash_edit_role' => '', 'splash_edit_user' => 'Пользователь сохранён', diff --git a/languages/sk_SK/lang.inc b/languages/sk_SK/lang.inc index ebe8543f3..45d061d75 100644 --- a/languages/sk_SK/lang.inc +++ b/languages/sk_SK/lang.inc @@ -476,8 +476,13 @@ URL: [url]', 'include_content' => '', 'include_documents' => 'Vrátane súborov', 'include_subdirectories' => 'Vrátane podzložiek', +'indexing_tasks_in_queue' => '', 'index_converters' => '', +'index_done' => '', +'index_error' => '', 'index_folder' => 'Indexovať zložku', +'index_pending' => '', +'index_waiting' => '', 'individuals' => 'Jednotlivci', 'indivіduals_in_groups' => '', 'inherited' => 'zdedené', @@ -672,6 +677,7 @@ URL: [url]', 'only_jpg_user_images' => 'Ako obrázky používateľov je možné použiť iba obrázky .jpg', 'order_by_sequence_off' => '', 'original_filename' => '', +'overall_indexing_progress' => '', 'owner' => 'Vlastník', 'ownership_changed_email' => 'Majitel zmeneny', 'ownership_changed_email_body' => '', @@ -738,6 +744,7 @@ URL: [url]', 'removed_revispr' => '', 'removed_workflow_email_body' => '', 'removed_workflow_email_subject' => '', +'removeFolderFromDropFolder' => '', 'remove_marked_files' => 'Zrušiť označenie súborov', 'repaired' => '', 'repairing_objects' => '', @@ -789,6 +796,7 @@ URL: [url]', 'rm_default_keyword_category' => 'Zmazať kategóriu', 'rm_document' => 'Odstrániť dokument', 'rm_document_category' => '', +'rm_event' => '', 'rm_file' => 'Odstrániť súbor', 'rm_folder' => 'Odstrániť zložku', 'rm_from_clipboard' => '', @@ -1188,9 +1196,11 @@ URL: [url]', 'splash_document_added' => '', 'splash_document_checkedout' => '', 'splash_document_edited' => '', +'splash_document_indexed' => '', 'splash_document_locked' => 'Dokument uzamknutý', 'splash_document_unlocked' => 'Dokument odomknutý', 'splash_edit_attribute' => '', +'splash_edit_event' => '', 'splash_edit_group' => '', 'splash_edit_role' => '', 'splash_edit_user' => '', diff --git a/languages/sv_SE/lang.inc b/languages/sv_SE/lang.inc index 49ae7ce04..d44ca6b6b 100644 --- a/languages/sv_SE/lang.inc +++ b/languages/sv_SE/lang.inc @@ -19,7 +19,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// Translators: Admin (1136), tmichelfelder (106) +// Translators: Admin (1138), tmichelfelder (106) $text = array( '2_factor_auth' => '', @@ -541,8 +541,13 @@ URL: [url]', 'include_content' => '', 'include_documents' => 'Inkludera dokument', 'include_subdirectories' => 'Inkludera under-kataloger', +'indexing_tasks_in_queue' => '', 'index_converters' => 'Omvandling av indexdokument', +'index_done' => '', +'index_error' => '', 'index_folder' => 'Index mapp', +'index_pending' => '', +'index_waiting' => '', 'individuals' => 'Personer', 'indivіduals_in_groups' => '', 'inherited' => 'ärvd', @@ -603,7 +608,7 @@ URL: [url]', 'keep' => '', 'keep_doc_status' => 'Bibehåll dokumentstatus', 'keywords' => 'Nyckelord', -'keywords_loading' => '', +'keywords_loading' => 'Vänta till nyckelordlistan har laddats', 'keyword_exists' => 'Nyckelordet finns redan', 'ko_KR' => 'Koreanska', 'language' => 'Språk', @@ -750,7 +755,7 @@ URL: [url]', 'no_update_cause_locked' => 'Därför kan du inte uppdatera detta dokument. Ta kontakt med användaren som låst dokumentet.', 'no_user_image' => 'Ingen bild hittades', 'no_version_check' => 'Fel vid sökning efter ny version av SeedDMS! Ursaken kan vara att allow_url_fopen i din php konfiguration är satt till 0.', -'no_version_modification' => '', +'no_version_modification' => 'Inga andra versioner finns', 'no_workflow_available' => '', 'objectcheck' => 'Katalog/Dokument-kontroll', 'object_check_critical' => '', @@ -761,6 +766,7 @@ URL: [url]', 'only_jpg_user_images' => 'Bara .jpg-bilder kan användas som användarbild', 'order_by_sequence_off' => '', 'original_filename' => 'Ursprungligt filnamn', +'overall_indexing_progress' => '', 'owner' => 'Ägare', 'ownership_changed_email' => 'Ägare har ändrats', 'ownership_changed_email_body' => 'Ägare har ändrats @@ -842,6 +848,7 @@ Arbetsflöde: [workflow] Användare: [username] URL: [url]', 'removed_workflow_email_subject' => '[sitename]: [name] - Arbetsflöde borttagen från dokument version', +'removeFolderFromDropFolder' => '', 'remove_marked_files' => 'Ta bort markerade filer', 'repaired' => 'repaired', 'repairing_objects' => 'Förbereder dokument och kataloger.', @@ -913,6 +920,7 @@ URL: [url]', 'rm_default_keyword_category' => 'Ta bort kategori', 'rm_document' => 'Ta bort', 'rm_document_category' => 'Ta bort kategori', +'rm_event' => '', 'rm_file' => 'Ta bort fil', 'rm_folder' => 'Ta bort katalog', 'rm_from_clipboard' => 'Ta bort från Urklipp', @@ -1319,9 +1327,11 @@ URL: [url]', 'splash_document_added' => '', 'splash_document_checkedout' => '', 'splash_document_edited' => 'Dokument sparad', +'splash_document_indexed' => '', 'splash_document_locked' => 'Dokument låst', 'splash_document_unlocked' => 'Dokument upplåst', 'splash_edit_attribute' => 'Attribut sparat', +'splash_edit_event' => '', 'splash_edit_group' => 'Grupp sparat', 'splash_edit_role' => '', 'splash_edit_user' => 'Användare sparat', diff --git a/languages/tr_TR/lang.inc b/languages/tr_TR/lang.inc index 9e89d5f76..607cfd5c8 100644 --- a/languages/tr_TR/lang.inc +++ b/languages/tr_TR/lang.inc @@ -19,7 +19,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// Translators: Admin (1046), aydin (83) +// Translators: Admin (1048), aydin (83) $text = array( '2_factor_auth' => '', @@ -399,7 +399,7 @@ URL: [url]', 'dump_creation_warning' => 'Bu işlemle veritabanınızın dump dosyasını oluşturabilirsiniz. Dump dosyası sunucunuzdaki data klasörüne kaydedilcektir.', 'dump_list' => 'Mevcut dump dosyaları', 'dump_remove' => 'Dump dosyasını sil', -'duplicate_content' => '', +'duplicate_content' => 'içeriği_klonla', 'edit' => 'Düzenle', 'edit_attributes' => 'Nitelikleri düzenle', 'edit_comment' => 'Açıklamayı düzenle', @@ -547,8 +547,13 @@ URL: [url]', 'include_content' => '', 'include_documents' => 'Dokümanları kapsa', 'include_subdirectories' => 'Alt klasörleri kapsa', +'indexing_tasks_in_queue' => '', 'index_converters' => 'Doküman dönüştürmeyi indeksle', +'index_done' => '', +'index_error' => '', 'index_folder' => 'Klasörü indeksle', +'index_pending' => '', +'index_waiting' => '', 'individuals' => 'Bireysel', 'indivіduals_in_groups' => '', 'inherited' => 'devralındı', @@ -767,6 +772,7 @@ URL: [url]', 'only_jpg_user_images' => 'Kullanıcı resmi olarak sadece .jpg uzantı resimler kullanılabilir', 'order_by_sequence_off' => '', 'original_filename' => 'Orijinal dosya adı', +'overall_indexing_progress' => '', 'owner' => 'Sahibi', 'ownership_changed_email' => 'Sahip değişti', 'ownership_changed_email_body' => 'Sahip değişti @@ -858,6 +864,7 @@ Klasör: [folder_path] Kullanıcı: [username] URL: [url]', 'removed_workflow_email_subject' => '[sitename]: [name] - Doküman versiyonundan iş akışı silindi', +'removeFolderFromDropFolder' => '', 'remove_marked_files' => 'İşaretli dosyaları sil', 'repaired' => 'onarıldı', 'repairing_objects' => 'Doküman ve klasörler onarılıyor.', @@ -929,6 +936,7 @@ URL: [url]', 'rm_default_keyword_category' => 'Kategoriyi sil', 'rm_document' => 'Dokümanı sil', 'rm_document_category' => 'Kategoriyi sil', +'rm_event' => '', 'rm_file' => 'Dosyayı sil', 'rm_folder' => 'Klasörü sil', 'rm_from_clipboard' => 'Panodan sil', @@ -1022,7 +1030,7 @@ URL: [url]', 'settings_Authentication' => 'Yetkilendirme ayarları', 'settings_autoLoginUser' => '', 'settings_autoLoginUser_desc' => '', -'settings_available_languages' => '', +'settings_available_languages' => 'kullanılabilir diller', 'settings_available_languages_desc' => '', 'settings_backupDir' => '', 'settings_backupDir_desc' => '', @@ -1335,9 +1343,11 @@ URL: [url]', 'splash_document_added' => 'Doküman eklendi', 'splash_document_checkedout' => '', 'splash_document_edited' => 'Doküman kaydedildi', +'splash_document_indexed' => '', 'splash_document_locked' => 'Doküman kilitlendi', 'splash_document_unlocked' => 'Doküman kiliti açıldı', 'splash_edit_attribute' => 'Nitelik kaydedildi', +'splash_edit_event' => '', 'splash_edit_group' => 'Grup kaydedildi', 'splash_edit_role' => '', 'splash_edit_user' => 'Kullanıcı kaydedildi', diff --git a/languages/uk_UA/lang.inc b/languages/uk_UA/lang.inc index e620c91d9..328451d0f 100644 --- a/languages/uk_UA/lang.inc +++ b/languages/uk_UA/lang.inc @@ -553,8 +553,13 @@ URL: [url]', 'include_content' => 'Включно з вмістом', 'include_documents' => 'Включно з документами', 'include_subdirectories' => 'Включно з підкаталогами', +'indexing_tasks_in_queue' => '', 'index_converters' => 'Індексування документів', +'index_done' => '', +'index_error' => '', 'index_folder' => 'Каталог індексу', +'index_pending' => '', +'index_waiting' => '', 'individuals' => 'Користувачі', 'indivіduals_in_groups' => 'Користувачі групи', 'inherited' => 'успадкований', @@ -772,6 +777,7 @@ URL: [url]', 'only_jpg_user_images' => 'Дозволені лише .jpg-зображення', 'order_by_sequence_off' => 'Можливість ручного сортування відключена в налаштуваннях. Якщо ви хочете використовувати цю функцію, ви повинні знову її включити.', 'original_filename' => 'Початкова назва файлу', +'overall_indexing_progress' => '', 'owner' => 'Власник', 'ownership_changed_email' => 'Власника змінено', 'ownership_changed_email_body' => 'Змінено власника @@ -864,6 +870,7 @@ URL: [url]', Користувач: [username] URL: [url]', 'removed_workflow_email_subject' => '[sitename]: видалено процес з версії документа «[name]»', +'removeFolderFromDropFolder' => '', 'remove_marked_files' => 'Видалити обрані файли', 'repaired' => 'виправлено', 'repairing_objects' => 'Відновлення каталогів і документів', @@ -950,6 +957,7 @@ URL: [url]', 'rm_default_keyword_category' => 'Видалити категорію', 'rm_document' => 'Видалити документ', 'rm_document_category' => 'Видалити категорію', +'rm_event' => '', 'rm_file' => 'Видалити файл', 'rm_folder' => 'Видалити каталог', 'rm_from_clipboard' => 'Видалити з буферу обміну', @@ -1356,9 +1364,11 @@ URL: [url]', 'splash_document_added' => 'Додано документ', 'splash_document_checkedout' => 'Документ відправлено на опрацювання', 'splash_document_edited' => 'Документ збережено', +'splash_document_indexed' => '', 'splash_document_locked' => 'Документ заблоковано', 'splash_document_unlocked' => 'Документ розблоковано', 'splash_edit_attribute' => 'Атрибут збережено', +'splash_edit_event' => '', 'splash_edit_group' => 'Групу збережено', 'splash_edit_role' => '', 'splash_edit_user' => 'Користувача збережено', diff --git a/languages/zh_CN/lang.inc b/languages/zh_CN/lang.inc index 710202cd4..a7c3f407c 100644 --- a/languages/zh_CN/lang.inc +++ b/languages/zh_CN/lang.inc @@ -19,7 +19,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// Translators: Admin (652), fengjohn (5) +// Translators: Admin (674), fengjohn (5) $text = array( '2_factor_auth' => '', @@ -203,7 +203,7 @@ URL: [url]', 'chart_docspercategory_title' => '目录文档数', 'chart_docspermimetype_title' => '', 'chart_docspermonth_title' => '每月创建的新文档', -'chart_docsperstatus_title' => '', +'chart_docsperstatus_title' => '各状态文档数', 'chart_docsperuser_title' => '单用户文档数', 'chart_selection' => '选择报表', 'chart_sizeperuser_title' => '单用户磁盘空间', @@ -237,7 +237,7 @@ URL: [url]', 'comment_changed_email' => '', 'comment_for_current_version' => '版本说明', 'confirm_clear_cache' => '', -'confirm_create_fulltext_index' => '', +'confirm_create_fulltext_index' => '确认重新创建全文索引', 'confirm_move_document' => '', 'confirm_move_folder' => '', 'confirm_pwd' => '确认密码', @@ -478,8 +478,13 @@ URL: [url]', 'include_content' => '', 'include_documents' => '包含文档', 'include_subdirectories' => '包含子目录', +'indexing_tasks_in_queue' => '', 'index_converters' => '索引文件转换', +'index_done' => '', +'index_error' => '', 'index_folder' => '索引目录', +'index_pending' => '', +'index_waiting' => '', 'individuals' => '个人', 'indivіduals_in_groups' => '', 'inherited' => '继承', @@ -674,6 +679,7 @@ URL: [url]', 'only_jpg_user_images' => '只用jpg格式的图片才可以作为用户身份图片', 'order_by_sequence_off' => '', 'original_filename' => '原始文件名', +'overall_indexing_progress' => '', 'owner' => '所有者', 'ownership_changed_email' => '所有者已变更', 'ownership_changed_email_body' => '', @@ -694,7 +700,7 @@ URL: [url]', 'password_send' => '', 'password_send_text' => '', 'password_strength' => '密码强度', -'password_strength_insuffient' => '', +'password_strength_insuffient' => '密码强度不够', 'password_wrong' => '', 'pending_approvals' => '', 'pending_reviews' => '', @@ -740,6 +746,7 @@ URL: [url]', 'removed_revispr' => '', 'removed_workflow_email_body' => '', 'removed_workflow_email_subject' => '', +'removeFolderFromDropFolder' => '', 'remove_marked_files' => '删除选中的文件', 'repaired' => '', 'repairing_objects' => '', @@ -791,6 +798,7 @@ URL: [url]', 'rm_default_keyword_category' => '删除类别', 'rm_document' => '删除文档', 'rm_document_category' => '删除分类', +'rm_event' => '', 'rm_file' => '删除文件', 'rm_folder' => '删除文件夹', 'rm_from_clipboard' => '从剪切板删除', @@ -884,8 +892,8 @@ URL: [url]', 'settings_cacheDir' => '', 'settings_cacheDir_desc' => '', 'settings_Calendar' => '', -'settings_calendarDefaultView' => '', -'settings_calendarDefaultView_desc' => '', +'settings_calendarDefaultView' => '日历默认试图', +'settings_calendarDefaultView_desc' => '日历默认试图', 'settings_cannot_disable' => '', 'settings_checkOutDir' => '', 'settings_checkOutDir_desc' => '', @@ -895,8 +903,8 @@ URL: [url]', 'settings_contentDir_desc' => '', 'settings_contentOffsetDir' => '内容偏移目录', 'settings_contentOffsetDir_desc' => '要解决在底层文件系统的限制,一个新的目录结构已制定了内容目录(内容目录)中存在的。这需要从它开始一个基本目录。通常离开这个为默认设置,1048576,也可以是内(内容目录)不存在任何数字或字符串', -'settings_convertToPdf' => '', -'settings_convertToPdf_desc' => '', +'settings_convertToPdf' => '将文档转换为pdf预览', +'settings_convertToPdf_desc' => '如果浏览器不支持原始文件预览,允许转换为pdf文件预览', 'settings_cookieLifetime' => '', 'settings_cookieLifetime_desc' => '', 'settings_coreDir' => 'SeedDMS核心目录', @@ -907,16 +915,16 @@ URL: [url]', 'settings_createdirectory' => '', 'settings_currentvalue' => '', 'settings_Database' => '数据库设置', -'settings_dbDatabase' => '', -'settings_dbDatabase_desc' => '', +'settings_dbDatabase' => '数据库名称', +'settings_dbDatabase_desc' => '设置连接的数据库', 'settings_dbDriver' => '', 'settings_dbDriver_desc' => '', -'settings_dbHostname' => '', -'settings_dbHostname_desc' => '', -'settings_dbPass' => '', -'settings_dbPass_desc' => '', -'settings_dbUser' => '', -'settings_dbUser_desc' => '', +'settings_dbHostname' => '数据库地址', +'settings_dbHostname_desc' => '设置数据库的连接地址', +'settings_dbPass' => '数据库密码', +'settings_dbPass_desc' => '填写连接数据库用户的密码', +'settings_dbUser' => '数据库用户', +'settings_dbUser_desc' => '设置连接数据库的用户', 'settings_dbVersion' => '', 'settings_defaultAccessDocs' => '', 'settings_defaultAccessDocs_desc' => '', @@ -932,7 +940,7 @@ URL: [url]', 'settings_dropFolderDir' => '', 'settings_dropFolderDir_desc' => '', 'settings_Edition' => '编辑设置', -'settings_editOnlineFileTypes' => '', +'settings_editOnlineFileTypes' => '编辑在线文件类型', 'settings_editOnlineFileTypes_desc' => '', 'settings_enable2FactorAuthentication' => '', 'settings_enable2FactorAuthentication_desc' => '', @@ -1013,7 +1021,7 @@ URL: [url]', 'settings_Extensions' => '', 'settings_extraPath' => '额外的PHP的include路径', 'settings_extraPath_desc' => '附加软件的路径。这是包含目录,例如在ADODB目录或额外的PEAR包', -'settings_firstDayOfWeek' => '', +'settings_firstDayOfWeek' => '每周第一天', 'settings_firstDayOfWeek_desc' => '', 'settings_footNote' => '附注', 'settings_footNote_desc' => '显示在每个页面底部的信息', @@ -1093,20 +1101,20 @@ URL: [url]', 'settings_previewWidthList_desc' => '列表中缩略图的宽度', 'settings_printDisclaimer' => '显示免责声明', 'settings_printDisclaimer_desc' => '如果开启,这个免责声明信息将在每个页面的底部显示', -'settings_quota' => '', +'settings_quota' => '设置磁盘配额', 'settings_quota_desc' => '', 'settings_removeFromDropFolder' => '', 'settings_removeFromDropFolder_desc' => '', 'settings_restricted' => '', 'settings_restricted_desc' => '', -'settings_rootDir' => '', +'settings_rootDir' => '根目录', 'settings_rootDir_desc' => '', 'settings_rootFolderID' => '', 'settings_rootFolderID_desc' => '', 'settings_SaveError' => '', -'settings_Server' => '', +'settings_Server' => '服务设置', 'settings_showFullPreview' => '显示完整的文档', -'settings_showFullPreview_desc' => '', +'settings_showFullPreview_desc' => '启用/禁用详细页面完整预览, 如果浏览器>支持的话', 'settings_showMissingTranslations' => '显示丢失的翻译', 'settings_showMissingTranslations_desc' => '', 'settings_showSingleSearchHit' => '', @@ -1169,7 +1177,7 @@ URL: [url]', 'set_expiry' => '设置截止日期', 'set_owner' => '设置所有者', 'set_owner_error' => '错误 设置所有者', -'set_password' => '', +'set_password' => '设定密码', 'set_workflow' => '', 'signed_in_as' => '登录为', 'sign_in' => '', @@ -1190,9 +1198,11 @@ URL: [url]', 'splash_document_added' => '', 'splash_document_checkedout' => '', 'splash_document_edited' => '', +'splash_document_indexed' => '', 'splash_document_locked' => '文档已被锁定', 'splash_document_unlocked' => '已解锁的文档', 'splash_edit_attribute' => '', +'splash_edit_event' => '', 'splash_edit_group' => '', 'splash_edit_role' => '', 'splash_edit_user' => '', diff --git a/languages/zh_TW/lang.inc b/languages/zh_TW/lang.inc index ae0f57797..0f74788b8 100644 --- a/languages/zh_TW/lang.inc +++ b/languages/zh_TW/lang.inc @@ -19,7 +19,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -// Translators: Admin (2374) +// Translators: Admin (2376) $text = array( '2_factor_auth' => '', @@ -476,8 +476,13 @@ URL: [url]', 'include_content' => '', 'include_documents' => '包含文檔', 'include_subdirectories' => '包含子目錄', +'indexing_tasks_in_queue' => '', 'index_converters' => '索引檔轉換', +'index_done' => '', +'index_error' => '', 'index_folder' => '索引目錄', +'index_pending' => '', +'index_waiting' => '', 'individuals' => '個人', 'indivіduals_in_groups' => '', 'inherited' => '繼承', @@ -672,6 +677,7 @@ URL: [url]', 'only_jpg_user_images' => '只用jpg格式的圖片才可以作為使用者身份圖片', 'order_by_sequence_off' => '', 'original_filename' => '', +'overall_indexing_progress' => '', 'owner' => '所有者', 'ownership_changed_email' => '所有者已變更', 'ownership_changed_email_body' => '', @@ -738,6 +744,7 @@ URL: [url]', 'removed_revispr' => '', 'removed_workflow_email_body' => '', 'removed_workflow_email_subject' => '', +'removeFolderFromDropFolder' => '', 'remove_marked_files' => '刪除勾選的檔案', 'repaired' => '', 'repairing_objects' => '', @@ -789,6 +796,7 @@ URL: [url]', 'rm_default_keyword_category' => '刪除類別', 'rm_document' => '刪除文檔', 'rm_document_category' => '刪除分類', +'rm_event' => '', 'rm_file' => '刪除檔', 'rm_folder' => '刪除資料夾', 'rm_from_clipboard' => '', @@ -1127,9 +1135,9 @@ URL: [url]', 'settings_smtpUser_desc' => '', 'settings_sortFoldersDefault' => '', 'settings_sortFoldersDefault_desc' => '', -'settings_sortFoldersDefault_val_name' => '', +'settings_sortFoldersDefault_val_name' => '按名称', 'settings_sortFoldersDefault_val_sequence' => '', -'settings_sortFoldersDefault_val_unsorted' => '', +'settings_sortFoldersDefault_val_unsorted' => '不排序', 'settings_sortUsersInList' => '', 'settings_sortUsersInList_desc' => '', 'settings_sortUsersInList_val_fullname' => '', @@ -1188,9 +1196,11 @@ URL: [url]', 'splash_document_added' => '', 'splash_document_checkedout' => '', 'splash_document_edited' => '', +'splash_document_indexed' => '', 'splash_document_locked' => '文檔已被鎖定', 'splash_document_unlocked' => '已解鎖的文檔', 'splash_edit_attribute' => '', +'splash_edit_event' => '', 'splash_edit_group' => '', 'splash_edit_role' => '', 'splash_edit_user' => '', diff --git a/op/op.AddDocument.php b/op/op.AddDocument.php index d3301ac44..7b077b0a6 100644 --- a/op/op.AddDocument.php +++ b/op/op.AddDocument.php @@ -240,12 +240,29 @@ if($settings->_dropFolderDir) { } } +if(isset($_POST['fineuploaderuuids']) && $_POST['fineuploaderuuids']) { + $uuids = explode(';', $_POST['fineuploaderuuids']); + $names = explode(';', $_POST['fineuploadernames']); + foreach($uuids as $i=>$uuid) { + $fullfile = $settings->_stagingDir.'/'.basename($uuid); + if(file_exists($fullfile)) { + $finfo = finfo_open(FILEINFO_MIME_TYPE); + $mimetype = finfo_file($finfo, $fullfile); + $_FILES["userfile"]['tmp_name'][] = $fullfile; + $_FILES["userfile"]['type'][] = $mimetype; + $_FILES["userfile"]['name'][] = isset($names[$i]) ? $names[$i] : $uuid; + $_FILES["userfile"]['size'][] = filesize($fullfile); + $_FILES["userfile"]['error'][] = 0; + } + } +} + /* Check files for Errors first */ for ($file_num=0;$file_num $folder->getName())),getMLText("uploading_zerosize")); } - if (is_uploaded_file($_FILES["userfile"]["tmp_name"][$file_num]) && $_FILES['userfile']['error'][$file_num]!=0){ + if (/* is_uploaded_file($_FILES["userfile"]["tmp_name"][$file_num]) && */$_FILES['userfile']['error'][$file_num]!=0){ UI::exitError(getMLText("folder_title", array("foldername" => $folder->getName())),getMLText("uploading_failed")); } } @@ -319,7 +336,15 @@ for ($file_num=0;$file_num_luceneDir); if($index) { $indexconf['Indexer']::init($settings->_stopWordsFile); - $index->addDocument(new $indexconf['IndexedDocument']($dms, $document, isset($settings->_converters['fulltext']) ? $settings->_converters['fulltext'] : null, !($filesize < $settings->_maxSizeForFullText))); + $idoc = new $indexconf['IndexedDocument']($dms, $document, isset($settings->_converters['fulltext']) ? $settings->_converters['fulltext'] : null, !($filesize < $settings->_maxSizeForFullText)); + if(isset($GLOBALS['SEEDDMS_HOOKS']['addDocument'])) { + foreach($GLOBALS['SEEDDMS_HOOKS']['addDocument'] as $hookObj) { + if (method_exists($hookObj, 'preIndexDocument')) { + $hookObj->preIndexDocument(null, $document, $idoc); + } + } + } + $index->addDocument($idoc); } } diff --git a/op/op.AddEvent.php b/op/op.AddEvent.php index ff3309128..c18aac653 100644 --- a/op/op.AddEvent.php +++ b/op/op.AddEvent.php @@ -27,7 +27,7 @@ include("../inc/inc.Extension.php"); include("../inc/inc.DBInit.php"); include("../inc/inc.Language.php"); include("../inc/inc.ClassUI.php"); -include("../inc/inc.Calendar.php"); +include("../inc/inc.ClassCalendar.php"); include("../inc/inc.Authentication.php"); if ($user->isGuest()) { @@ -66,7 +66,9 @@ if ($to<=$from){ UI::exitError(getMLText("add_event"),getMLText("to_before_from")); } -$res = addEvent($from, $to, $name, $comment); +$calendar = new SeedDMS_Calendar($dms->getDB(), $user); + +$res = $calendar->addEvent($from, $to, $name, $comment); if (is_bool($res) && !$res) { UI::exitError(getMLText("add_event"),getMLText("error_occured")); diff --git a/op/op.AddFile.php b/op/op.AddFile.php index c18d41737..a1507cf13 100644 --- a/op/op.AddFile.php +++ b/op/op.AddFile.php @@ -44,69 +44,75 @@ if ($document->getAccessMode($user) < M_READWRITE) { UI::exitError(getMLText("document_title", array("documentname" => $document->getName())),getMLText("access_denied")); } -if (is_uploaded_file($_FILES["userfile"]["tmp_name"]) && $_FILES["userfile"]["size"] > 0 && $_FILES['userfile']['error']!=0){ - UI::exitError(getMLText("folder_title", array("foldername" => $folder->getName())),getMLText("uploading_failed")); -} - -$name = $_POST["name"]; -$comment = $_POST["comment"]; - -if($_FILES["userfile"]["error"]) { - UI::exitError(getMLText("folder_title", array("foldername" => $folder->getName())),getMLText("error_occured")); -} - -$userfiletmp = $_FILES["userfile"]["tmp_name"]; -$userfiletype = $_FILES["userfile"]["type"]; -$userfilename = $_FILES["userfile"]["name"]; - -$fileType = ".".pathinfo($userfilename, PATHINFO_EXTENSION); - -if($settings->_overrideMimeType) { - $finfo = finfo_open(FILEINFO_MIME_TYPE); - $userfiletype = finfo_file($finfo, $userfiletmp); -} - -$res = $document->addDocumentFile($name, $comment, $user, $userfiletmp, - basename($userfilename),$fileType, $userfiletype ); - -if (is_bool($res) && !$res) { - UI::exitError(getMLText("folder_title", array("foldername" => $folder->getName())),getMLText("error_occured")); -} else { - // Send notification to subscribers. - if($notifier) { - $notifyList = $document->getNotifyList(); - -/* - $subject = "###SITENAME###: ".$document->getName()." - ".getMLText("new_file_email"); - $message = getMLText("new_file_email")."\r\n"; - $message .= - getMLText("name").": ".$name."\r\n". - getMLText("comment").": ".$comment."\r\n". - getMLText("user").": ".$user->getFullName()." <". $user->getEmail() .">\r\n". - "URL: ###URL_PREFIX###out/out.ViewDocument.php?documentid=".$document->getID()."\r\n"; - - $subject=$subject; - $message=$message; - - $notifier->toList($user, $document->_notifyList["users"], $subject, $message); - foreach ($document->_notifyList["groups"] as $grp) { - $notifier->toGroup($user, $grp, $subject, $message); +if(isset($_POST['fineuploaderuuids']) && $_POST['fineuploaderuuids']) { + $uuids = explode(';', $_POST['fineuploaderuuids']); + $names = explode(';', $_POST['fineuploadernames']); + foreach($uuids as $i=>$uuid) { + $fullfile = $settings->_stagingDir.'/'.basename($uuid); + if(file_exists($fullfile)) { + $finfo = finfo_open(FILEINFO_MIME_TYPE); + $mimetype = finfo_file($finfo, $fullfile); + $_FILES["userfile"]['tmp_name'][] = $fullfile; + $_FILES["userfile"]['type'][] = $mimetype; + $_FILES["userfile"]['name'][] = isset($names[$i]) ? $names[$i] : $uuid; + $_FILES["userfile"]['size'][] = filesize($fullfile); + $_FILES["userfile"]['error'][] = 0; } -*/ + } +} - $subject = "new_file_email_subject"; - $message = "new_file_email_body"; - $params = array(); - $params['name'] = $name; - $params['document'] = $document->getName(); - $params['username'] = $user->getFullName(); - $params['comment'] = $comment; - $params['url'] = "http".((isset($_SERVER['HTTPS']) && (strcmp($_SERVER['HTTPS'],'off')!=0)) ? "s" : "")."://".$_SERVER['HTTP_HOST'].$settings->_httpRoot."out/out.ViewDocument.php?documentid=".$document->getID(); - $params['sitename'] = $settings->_siteName; - $params['http_root'] = $settings->_httpRoot; - $notifier->toList($user, $notifyList["users"], $subject, $message, $params); - foreach ($notifyList["groups"] as $grp) { - $notifier->toGroup($user, $grp, $subject, $message, $params); +for ($file_num=0;$file_num $document->getName())),getMLText("uploading_zerosize")); + } + if (is_uploaded_file($_FILES["userfile"]["tmp_name"][$file_num]) && $_FILES['userfile']['error'][$file_num] != 0){ + UI::exitError(getMLText("document_title", array("documentname" => $document->getName())),getMLText("uploading_failed")); + } + if($_FILES["userfile"]["error"][$file_num]) { + UI::exitError(getMLText("document_title", array("documentname" => $document->getName())),getMLText("error_occured")); + } + + if(count($_FILES["userfile"]["tmp_name"]) == 1 && !empty($_POST['name'])) + $name = $_POST["name"]; + else + $name = $_FILES["userfile"]['name'][$file_num]; + $comment = $_POST["comment"]; + + $userfiletmp = $_FILES["userfile"]["tmp_name"][$file_num]; + $userfiletype = $_FILES["userfile"]["type"][$file_num]; + $userfilename = $_FILES["userfile"]["name"][$file_num]; + + $fileType = ".".pathinfo($userfilename, PATHINFO_EXTENSION); + + if($settings->_overrideMimeType) { + $finfo = finfo_open(FILEINFO_MIME_TYPE); + $userfiletype = finfo_file($finfo, $userfiletmp); + } + + $res = $document->addDocumentFile($name, $comment, $user, $userfiletmp, + basename($userfilename),$fileType, $userfiletype ); + + if (is_bool($res) && !$res) { + UI::exitError(getMLText("folder_title", array("foldername" => $folder->getName())),getMLText("error_occured")); + } else { + // Send notification to subscribers. + if($notifier) { + $notifyList = $document->getNotifyList(); + + $subject = "new_file_email_subject"; + $message = "new_file_email_body"; + $params = array(); + $params['name'] = $name; + $params['document'] = $document->getName(); + $params['username'] = $user->getFullName(); + $params['comment'] = $comment; + $params['url'] = "http".((isset($_SERVER['HTTPS']) && (strcmp($_SERVER['HTTPS'],'off')!=0)) ? "s" : "")."://".$_SERVER['HTTP_HOST'].$settings->_httpRoot."out/out.ViewDocument.php?documentid=".$document->getID(); + $params['sitename'] = $settings->_siteName; + $params['http_root'] = $settings->_httpRoot; + $notifier->toList($user, $notifyList["users"], $subject, $message, $params); + foreach ($notifyList["groups"] as $grp) { + $notifier->toGroup($user, $grp, $subject, $message, $params); + } } } } diff --git a/op/op.Ajax.php b/op/op.Ajax.php index 4d0e80b4a..766bb6a93 100644 --- a/op/op.Ajax.php +++ b/op/op.Ajax.php @@ -251,7 +251,7 @@ switch($command) { } else { $mfolder = $dms->getFolder($_REQUEST['folderid']); if($mfolder) { - if ($mfolder->getAccessMode($user) >= M_READ) { + if ($mfolder->getAccessMode($user) >= M_READWRITE) { if($folder = $dms->getFolder($_REQUEST['targetfolderid'])) { if($folder->getAccessMode($user) >= M_READWRITE) { if($mfolder->setParent($folder)) { @@ -290,7 +290,7 @@ switch($command) { } else { $mdocument = $dms->getDocument($_REQUEST['docid']); if($mdocument) { - if ($mdocument->getAccessMode($user) >= M_READ) { + if ($mdocument->getAccessMode($user) >= M_READWRITE) { if($folder = $dms->getFolder($_REQUEST['targetfolderid'])) { if($folder->getAccessMode($user) >= M_READWRITE) { if($mdocument->setFolder($folder)) { @@ -671,8 +671,8 @@ switch($command) { } } - if(isset($GLOBALS['SEEDDMS_HOOKS']['postAddDocument'])) { - foreach($GLOBALS['SEEDDMS_HOOKS']['postAddDocument'] as $hookObj) { + if(isset($GLOBALS['SEEDDMS_HOOKS']['addDocument'])) { + foreach($GLOBALS['SEEDDMS_HOOKS']['addDocument'] as $hookObj) { if (method_exists($hookObj, 'postAddDocument')) { $hookObj->postAddDocument($document); } @@ -682,7 +682,15 @@ switch($command) { $index = $indexconf['Indexer']::open($settings->_luceneDir); if($index) { $indexconf['Indexer']::init($settings->_stopWordsFile); - $index->addDocument(new $indexconf['IndexedDocument']($dms, $document, isset($settings->_converters['fulltext']) ? $settings->_converters['fulltext'] : null, !($filesize < $settings->_maxSizeForFullText))); + $idoc = new $indexconf['IndexedDocument']($dms, $document, isset($settings->_converters['fulltext']) ? $settings->_converters['fulltext'] : null, !($filesize < $settings->_maxSizeForFullText)); + if(isset($GLOBALS['SEEDDMS_HOOKS']['addDocument'])) { + foreach($GLOBALS['SEEDDMS_HOOKS']['addDocument'] as $hookObj) { + if (method_exists($hookObj, 'preIndexDocument')) { + $hookObj->preIndexDocument($document, $idoc); + } + } + } + $index->addDocument($idoc); } } @@ -738,5 +746,38 @@ switch($command) { } break; /* }}} */ + case 'indexdocument': /* {{{ */ + if($user && $user->isAdmin()) { + if($settings->_enableFullSearch) { + $document = $dms->getDocument($_REQUEST['id']); + if($document) { + $index = $indexconf['Indexer']::open($settings->_luceneDir); + if($index) { + $indexconf['Indexer']::init($settings->_stopWordsFile); + $idoc = new $indexconf['IndexedDocument']($dms, $document, isset($settings->_converters['fulltext']) ? $settings->_converters['fulltext'] : null, false); + if(isset($GLOBALS['SEEDDMS_HOOKS']['indexDocument'])) { + foreach($GLOBALS['SEEDDMS_HOOKS']['indexDocument'] as $hookObj) { + if (method_exists($hookObj, 'preIndexDocument')) { + $hookObj->preIndexDocument(null, $document, $idoc); + } + } + } + $index->addDocument($idoc); + header('Content-Type: application/json'); + echo json_encode(array('success'=>true, 'message'=>getMLText('splash_document_indexed'), 'data'=>$document->getID())); + } else { + header('Content-Type: application/json'); + echo json_encode(array('success'=>false, 'message'=>getMLText('error_occured'), 'data'=>$document->getID())); + } + } else { + header('Content-Type: application/json'); + echo json_encode(array('success'=>false, 'message'=>getMLText('invalid_doc_id'), 'data'=>'')); + } + } else { + header('Content-Type: application/json'); + echo json_encode(array('success'=>false, 'message'=>getMLText('error_occured'), 'data'=>'')); + } + } + break; /* }}} */ } ?> diff --git a/op/op.EditEvent.php b/op/op.EditEvent.php index 3fdf9396c..b287e40ae 100644 --- a/op/op.EditEvent.php +++ b/op/op.EditEvent.php @@ -27,7 +27,7 @@ include("../inc/inc.Init.php"); include("../inc/inc.Extension.php"); include("../inc/inc.DBInit.php"); include("../inc/inc.ClassUI.php"); -include("../inc/inc.Calendar.php"); +include("../inc/inc.ClassCalendar.php"); include("../inc/inc.Authentication.php"); if ($user->isGuest()) { @@ -43,46 +43,60 @@ if (!isset($_POST["from"]) && !(isset($_POST["frommonth"]) && isset($_POST["from UI::exitError(getMLText("edit_event"),getMLText("error_occured")); } -if (!isset($_POST["to"]) && !(isset($_POST["tomonth"]) && isset($_POST["today"]) && isset($_POST["toyear"])) ) { +$calendar = new SeedDMS_Calendar($dms->getDB(), $user); + +if (!isset($_POST["eventid"]) || !($event = $calendar->getEvent($_POST["eventid"]))) { UI::exitError(getMLText("edit_event"),getMLText("error_occured")); } -if (!isset($_POST["name"]) || !isset($_POST["comment"]) ) { - UI::exitError(getMLText("edit_event"),getMLText("error_occured")); -} +/* Not setting name or comment will leave them untouched */ +if (!isset($_POST["name"])) + $name = null; +else + $name = $_POST["name"]; -if (!isset($_POST["eventid"])) { - UI::exitError(getMLText("edit_event"),getMLText("error_occured")); -} +if (!isset($_POST["comment"])) + $comment = null; +else + $comment = $_POST["comment"]; -$name = $_POST["name"]; -$comment = $_POST["comment"]; if(isset($_POST["from"])) { $tmp = explode('-', $_POST["from"]); $from = mktime(0,0,0, $tmp[1], $tmp[2], $tmp[0]); } else { - $from = mktime(0,0,0, intval($_POST["frommonth"]), intval($_POST["fromday"]), intval($_POST["fromyear"])); + UI::exitError(getMLText("edit_event"),getMLText("error_occured")); } if(isset($_POST["to"])) { $tmp = explode('-', $_POST["to"]); $to = mktime(23,59,59, $tmp[1], $tmp[2], $tmp[0]); } else { - $to = mktime(23,59,59, intval($_POST["tomonth"]), intval($_POST["today"]), intval($_POST["toyear"])); + $to = $event['stop'] - $event['start'] + $from;; } -if ($to<=$from){ +if ($to !== null && $to<=$from){ $to = $from + 86400 -1; } -$res = editEvent($_POST["eventid"], $from, $to, $name, $comment ); +$res = $calendar->editEvent($_POST["eventid"], $from, $to, $name, $comment ); -if (is_bool($res) && !$res) { - UI::exitError(getMLText("edit_event"),getMLText("error_occured")); +if(isset($_POST["ajax"]) && $_POST["ajax"]) { + header('Content-Type: application/json'); + if (is_bool($res) && !$res) + echo json_encode(array('success'=>false, 'message'=>getMLText('error_occured'))); + else { + echo json_encode(array('success'=>true, 'message'=>getMLText('splash_edit_event'))); + add_log_line("?eventid=".$_POST["eventid"]."&name=".$name."&from=".$from."&to=".$to); + } +} else { + if (is_bool($res) && !$res) { + UI::exitError(getMLText("edit_event"),getMLText("error_occured")); + } + + $session->setSplashMsg(array('type'=>'success', 'msg'=>getMLText('splash_edit_event'))); + + add_log_line("?eventid=".$_POST["eventid"]."&name=".$name."&from=".$from."&to=".$to); + + header("Location:../out/out.Calendar.php?mode=w&day=".$_POST["fromday"]."&year=".$_POST["fromyear"]."&month=".$_POST["frommonth"]); } -add_log_line("?eventid=".$_POST["eventid"]."&name=".$name."&from=".$from."&to=".$to); - -header("Location:../out/out.Calendar.php?mode=w&day=".$_POST["fromday"]."&year=".$_POST["fromyear"]."&month=".$_POST["frommonth"]); - - ?> diff --git a/op/op.ImportFS.php b/op/op.ImportFS.php index 3b5760dbf..83dd8ed67 100644 --- a/op/op.ImportFS.php +++ b/op/op.ImportFS.php @@ -42,8 +42,9 @@ if ($folder->getAccessMode($user) < M_READWRITE) { if (empty($_GET["dropfolderfileform1"])) { UI::exitError(getMLText("admin_tools"),getMLText("invalid_target_folder")); } -$dirname = $settings->_dropFolderDir.'/'.$user->getLogin()."/".$_GET["dropfolderfileform1"]; -if(!is_dir($dirname)) { + +$dirname = realpath($settings->_dropFolderDir.'/'.$user->getLogin()."/".$_GET["dropfolderfileform1"]); +if(strpos($dirname, realpath($settings->_dropFolderDir.'/'.$user->getLogin().'/')) !== 0 || !is_dir($dirname)) { UI::exitError(getMLText("admin_tools"),getMLText("invalid_dropfolder_folder")); } @@ -104,8 +105,14 @@ $foldercount = $doccount = 0; if($newfolder = $folder->addSubFolder($_GET["dropfolderfileform1"], '', $user, 1)) { if(!import_folder($dirname, $newfolder)) $session->setSplashMsg(array('type'=>'error', 'msg'=>getMLText('error_importfs'))); - else + else { + if(isset($_GET['remove']) && $_GET["remove"]) { + $cmd = 'rm -rf '.$dirname; + $ret = null; + system($cmd, $ret); + } $session->setSplashMsg(array('type'=>'success', 'msg'=>getMLText('splash_importfs', array('docs'=>$doccount, 'folders'=>$foldercount)))); + } } else { $session->setSplashMsg(array('type'=>'error', 'msg'=>getMLText('error_importfs'))); } diff --git a/op/op.PdfPreview.php b/op/op.PdfPreview.php new file mode 100644 index 000000000..48c85485f --- /dev/null +++ b/op/op.PdfPreview.php @@ -0,0 +1,77 @@ +getDocument($documentid); +if (!is_object($document)) { + exit; +} + +if ($document->getAccessMode($user) < M_READ) { + exit; +} + +if(isset($_GET['version'])) { + $version = $_GET["version"]; + if (!is_numeric($version)) + exit; + if(intval($version)<1) + $object = $document->getLatestContent(); + else + $object = $document->getContentByVersion($version); +} elseif(isset($_GET['file'])) { + $file = $_GET['file']; + if (!is_numeric($file) || intval($file)<1) + exit; + $object = $document->getDocumentFile($file); +} else { + exit; +} + +if (!is_object($object)) { + exit; +} + +$previewer = new SeedDMS_Preview_PdfPreviewer($settings->_cacheDir); +if(!$previewer->hasPreview($object)) + $previewer->createPreview($object); +header('Content-Type: application/pdf'); +$previewer->getPreview($object); + diff --git a/op/op.RemoveEvent.php b/op/op.RemoveEvent.php index 395686d89..998671038 100644 --- a/op/op.RemoveEvent.php +++ b/op/op.RemoveEvent.php @@ -27,7 +27,7 @@ include("../inc/inc.Init.php"); include("../inc/inc.Extension.php"); include("../inc/inc.DBInit.php"); include("../inc/inc.ClassUI.php"); -include("../inc/inc.Calendar.php"); +include("../inc/inc.ClassCalendar.php"); include("../inc/inc.Authentication.php"); /* Check if the form data comes from a trusted request */ @@ -39,13 +39,14 @@ if (!isset($_POST["eventid"]) || !is_numeric($_POST["eventid"]) || intval($_POST UI::exitError(getMLText("edit_event"),getMLText("error_occured")); } -$event=getEvent($_POST["eventid"]); +$calendar = new SeedDMS_Calendar($dms->getDB(), $user); +$event=$calendar->getEvent($_POST["eventid"]); if (($user->getID()!=$event["userID"])&&(!$user->isAdmin())){ UI::exitError(getMLText("edit_event"),getMLText("access_denied")); } -$res = delEvent($_POST["eventid"]); +$res = $calendar->delEvent($_POST["eventid"]); if (is_bool($res) && !$res) { UI::exitError(getMLText("edit_event"),getMLText("error_occured")); diff --git a/op/op.UpdateDocument.php b/op/op.UpdateDocument.php index e54054bd9..25547ef9c 100644 --- a/op/op.UpdateDocument.php +++ b/op/op.UpdateDocument.php @@ -58,14 +58,30 @@ if ($document->isLocked()) { else $document->setLocked(false); } +if(isset($_POST['fineuploaderuuids']) && $_POST['fineuploaderuuids']) { + $uuids = explode(';', $_POST['fineuploaderuuids']); + $names = explode(';', $_POST['fineuploadernames']); + $uuid = $uuids[0]; + $fullfile = $settings->_stagingDir.'/'.basename($uuid); + if(file_exists($fullfile)) { + $finfo = finfo_open(FILEINFO_MIME_TYPE); + $mimetype = finfo_file($finfo, $fullfile); + $_FILES["userfile"]['tmp_name'] = $fullfile; + $_FILES["userfile"]['type'] = $mimetype; + $_FILES["userfile"]['name'] = isset($names[0]) ? $names[0] : $uuid; + $_FILES["userfile"]['size'] = filesize($fullfile); + $_FILES["userfile"]['error'] = 0; + } +} + if(isset($_POST["comment"])) $comment = $_POST["comment"]; else $comment = ""; if ($_FILES['userfile']['error'] == 0) { - if(!is_uploaded_file($_FILES["userfile"]["tmp_name"])) - UI::exitError(getMLText("document_title", array("documentname" => $document->getName())),getMLText("error_occured")); +// if(!is_uploaded_file($_FILES["userfile"]["tmp_name"])) +// UI::exitError(getMLText("document_title", array("documentname" => $document->getName())),getMLText("error_occured")."lsajdflk"); if($_FILES["userfile"]["size"] == 0) UI::exitError(getMLText("document_title", array("documentname" => $document->getName())),getMLText("uploading_zerosize")); @@ -221,12 +237,27 @@ if ($_FILES['userfile']['error'] == 0) { $attributes = array(); } + if(isset($GLOBALS['SEEDDMS_HOOKS']['updateDocument'])) { + foreach($GLOBALS['SEEDDMS_HOOKS']['updateDocument'] as $hookObj) { + if (method_exists($hookObj, 'preUpdateDocument')) { + $hookObj->preUpdateDocument(array('name'=>&$name, 'comment'=>&$comment)); + } + } + } + $filesize = SeedDMS_Core_File::fileSize($userfiletmp); $contentResult=$document->addContent($comment, $user, $userfiletmp, basename($userfilename), $fileType, $userfiletype, $reviewers, $approvers, $version=0, $attributes, $workflow); if (is_bool($contentResult) && !$contentResult) { UI::exitError(getMLText("document_title", array("documentname" => $document->getName())),getMLText("error_occured")); } else { + if(isset($GLOBALS['SEEDDMS_HOOKS']['updateDocument'])) { + foreach($GLOBALS['SEEDDMS_HOOKS']['updateDocument'] as $hookObj) { + if (method_exists($hookObj, 'postUpdateDocument')) { + $hookObj->postUpdateDocument($document); + } + } + } if($settings->_enableFullSearch) { $index = $indexconf['Indexer']::open($settings->_luceneDir); if($index) { @@ -235,7 +266,15 @@ if ($_FILES['userfile']['error'] == 0) { $index->delete($hit->id); } $indexconf['Indexer']::init($settings->_stopWordsFile); - $index->addDocument(new $indexconf['IndexedDocument']($dms, $document, isset($settings->_converters['fulltext']) ? $settings->_converters['fulltext'] : null, !($filesize < $settings->_maxSizeForFullText))); + $idoc = new $indexconf['IndexedDocument']($dms, $document, isset($settings->_converters['fulltext']) ? $settings->_converters['fulltext'] : null, !($filesize < $settings->_maxSizeForFullText)); + if(isset($GLOBALS['SEEDDMS_HOOKS']['updateDocument'])) { + foreach($GLOBALS['SEEDDMS_HOOKS']['updateDocument'] as $hookObj) { + if (method_exists($hookObj, 'preIndexDocument')) { + $hookObj->preIndexDocument(null, $document, $idoc); + } + } + } + $index->addDocument($idoc); $index->commit(); } } diff --git a/op/op.UploadChunks.php b/op/op.UploadChunks.php new file mode 100644 index 000000000..30d82ebe9 --- /dev/null +++ b/op/op.UploadChunks.php @@ -0,0 +1,66 @@ +_stagingDir.$fileId."-".$partitionIndex; +if( move_uploaded_file( $source_file_path, $target_file_path ) ) { + if($partitionIndex+1 == $totalparts) { + if($fpnew = fopen($settings->_stagingDir.$fileId, 'w+')) { + for($i=0; $i<$totalparts; $i++) { + $content = file_get_contents($settings->_stagingDir.$fileId."-".$i, 'r'); + fwrite($fpnew, $content); + unlink($settings->_stagingDir.$fileId."-".$i); + } + fclose($fpnew); + header("Content-Type: text/plain"); + echo json_encode(array('success'=>true)); + exit; + } else { + header("Content-Type: text/plain"); + echo json_encode(array('success'=>false, 'error'=>'Could not upload file')); + exit; + } + } + header("Content-Type: text/plain"); + echo json_encode(array('success'=>true)); + exit; +} +header("Content-Type: text/plain"); +echo json_encode(array('success'=>false, 'error'=>'Could not upload file')); +?> diff --git a/out/out.AddEvent.php b/out/out.AddEvent.php index fd423da19..959da8ad8 100644 --- a/out/out.AddEvent.php +++ b/out/out.AddEvent.php @@ -32,6 +32,7 @@ if ($user->isGuest()) { $tmp = explode('.', basename($_SERVER['SCRIPT_FILENAME'])); $view = UI::factory($theme, $tmp[1], array('dms'=>$dms, 'user'=>$user)); if($view) { + $view->setParam('strictformcheck', $settings->_strictFormCheck); $view($_GET); exit; } diff --git a/out/out.AdminTools.php b/out/out.AdminTools.php index 0fcfd0f58..210ff2329 100644 --- a/out/out.AdminTools.php +++ b/out/out.AdminTools.php @@ -18,6 +18,7 @@ // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. include("../inc/inc.Settings.php"); +include("../inc/inc.LogInit.php"); include("../inc/inc.Language.php"); include("../inc/inc.Init.php"); include("../inc/inc.Extension.php"); diff --git a/out/out.Calendar.php b/out/out.Calendar.php index ef88256b3..7620673dd 100644 --- a/out/out.Calendar.php +++ b/out/out.Calendar.php @@ -18,7 +18,7 @@ // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. include("../inc/inc.Settings.php"); -include("../inc/inc.Calendar.php"); +include("../inc/inc.ClassCalendar.php"); include("../inc/inc.Language.php"); include("../inc/inc.Init.php"); include("../inc/inc.Extension.php"); @@ -26,26 +26,51 @@ include("../inc/inc.DBInit.php"); include("../inc/inc.ClassUI.php"); include("../inc/inc.Authentication.php"); -if ($_GET["mode"]) $mode=$_GET["mode"]; +if (isset($_GET["start"])) $start=$_GET["start"]; +else $start = ''; +if (isset($_GET["end"])) $end=$_GET["end"]; +else $end = ''; -// get required date else use current -$currDate = time(); +if(isset($_GET['documentid']) && $_GET['documentid'] && is_numeric($_GET['documentid'])) { + $document = $dms->getDocument($_GET["documentid"]); + if (!is_object($document)) { + $view->exitError(getMLText("document_title", array("documentname" => getMLText("invalid_doc_id"))),getMLText("invalid_doc_id")); + } +} else + $document = null; -if (isset($_GET["year"])&&is_numeric($_GET["year"])) $year=$_GET["year"]; -else $year = (int)date("Y", $currDate); -if (isset($_GET["month"])&&is_numeric($_GET["month"])) $month=$_GET["month"]; -else $month = (int)date("m", $currDate); -if (isset($_GET["day"])&&is_numeric($_GET["day"])) $day=$_GET["day"]; -else $day = (int)date("d", $currDate); +$calendar = new SeedDMS_Calendar($dms->getDB(), $user); + +if(isset($_GET['eventid']) && $_GET['eventid'] && is_numeric($_GET['eventid'])) { + $event = $calendar->getEvent($_GET["eventid"]); +} else + $event = null; + +if(isset($_GET['version']) && $_GET['version'] && is_numeric($_GET['version'])) { + $content = $document->getContentByVersion($_GET['version']); +} else + $content = null; + +if(isset($_GET['eventtype']) && $_GET['eventtype']) { + $eventtype = $_GET['eventtype']; +} else + $eventtype = 'regular'; $tmp = explode('.', basename($_SERVER['SCRIPT_FILENAME'])); $view = UI::factory($theme, $tmp[1], array('dms'=>$dms, 'user'=>$user)); if($view) { - $view->setParam('mode', $mode); - $view->setParam('year', $year); - $view->setParam('month', $month); - $view->setParam('day', $day); - $view->setParam('firstdayofweek', $settings->_firstDayOfWeek); + $view->setParam('calendar', $calendar); + $view->setParam('start', $start); + $view->setParam('end', $end); + $view->setParam('document', $document); + $view->setParam('version', $content); + $view->setParam('event', $event); + $view->setParam('strictformcheck', $settings->_strictFormCheck); + $view->setParam('eventtype', $eventtype); + $view->setParam('cachedir', $settings->_cacheDir); + $view->setParam('previewWidthList', $settings->_previewWidthList); + $view->setParam('previewWidthDetail', $settings->_previewWidthDetail); + $view->setParam('timeout', $settings->_cmdTimeout); $view($_GET); exit; } diff --git a/out/out.Indexer.php b/out/out.Indexer.php index 95aae671e..cd8a323d1 100644 --- a/out/out.Indexer.php +++ b/out/out.Indexer.php @@ -69,6 +69,7 @@ if($view) { $view->setParam('index', $index); $view->setParam('indexconf', $indexconf); $view->setParam('recreate', (isset($_GET['create']) && $_GET['create']==1)); + $view->setParam('forceupdate', (isset($_GET['forceupdate']) && $_GET['forceupdate']==1)); $view->setParam('folder', $folder); $view->setParam('converters', $settings->_converters['fulltext']); $view->setParam('timeout', $settings->_cmdTimeout); diff --git a/restapi/index.php b/restapi/index.php index 78e48e6c5..7bf436660 100644 --- a/restapi/index.php +++ b/restapi/index.php @@ -3,6 +3,7 @@ define('USE_PHP_SESSION', 0); include("../inc/inc.Settings.php"); require_once "SeedDMS/Core.php"; +require_once "SeedDMS/Preview.php"; $db = new SeedDMS_Core_DatabaseAccess($settings->_dbDriver, $settings->_dbHostname, $settings->_dbUser, $settings->_dbPass, $settings->_dbDatabase); $db->connect() or die ("Could not connect to db-server \"" . $settings->_dbHostname . "\""); @@ -52,8 +53,9 @@ if(USE_PHP_SESSION) { } -require 'Slim/Slim.php'; -\Slim\Slim::registerAutoloader(); +#require 'Slim/Slim.php'; +require "vendor/autoload.php"; +#\Slim\Slim::registerAutoloader(); function doLogin() { /* {{{ */ global $app, $dms, $userobj, $session, $settings; diff --git a/styles/bootstrap/application.css b/styles/bootstrap/application.css index 7e905867e..ea8dc1835 100644 --- a/styles/bootstrap/application.css +++ b/styles/bootstrap/application.css @@ -54,6 +54,14 @@ ul.jqtree-tree li.jqtree-selected > .jqtree-element:hover { font-weight: bold; } +td.today { + background-color: rgb(255, 200, 0); +} + +td.event { + background-color: rgb(0, 200, 255); +} + .wordbreak { word-break: break-word; } @@ -206,6 +214,45 @@ div.popupbox span.closepopupbox { top: 0px; } +ul.qq-upload-list { + /* + background-color: #fff; + border-radius: 4px; + border: 1px solid #cccccc; + */ +} + +ul.qq-upload-list li { + display: inline-block; + margin: 5px 5px 5px 0; + padding: 5px; + background-color: #fff; + border: 1px solid #cccccc; + border-radius: 4px; +} + +ul.qq-upload-list li img { + display: block; +} + +ul.qq-upload-list li span { + display: block; +} + +.qq-upload-button { + display: inline-block; +} + +.qq-upload-drop-area { + display: inline-block; + width: 200px; + height: 22px; + padding: 3px; + background-color: #fff; + border: 1px solid #cccccc; + border-radius: 4px; +} + @media (max-width: 480px) { .nav-tabs > li { float:none; diff --git a/styles/bootstrap/application.js b/styles/bootstrap/application.js index 935d9bf30..731782192 100644 --- a/styles/bootstrap/application.js +++ b/styles/bootstrap/application.js @@ -385,7 +385,7 @@ $(document).ready( function() { }); }); /* }}} */ - $('div.ajax').on('update', function(event, param1) { /* {{{ */ + $('div.ajax').on('update', function(event, param1, callback) { /* {{{ */ var element = $(this); var url = ''; var href = element.data('href'); @@ -397,7 +397,10 @@ $(document).ready( function() { url = href; if(typeof param1 === 'object') { for(var key in param1) { - url += "&"+key+"="+param1[key]; + if(key == 'callback') + callback = param1[key]; + else + url += "&"+key+"="+param1[key]; } } else { url += "&"+param1; @@ -432,6 +435,8 @@ $(document).ready( function() { } } }); /* }}} */ + if(callback) + callback.call(); }); }); /* }}} */ diff --git a/styles/bootstrap/fine-uploader/LICENSE b/styles/bootstrap/fine-uploader/LICENSE new file mode 100644 index 000000000..3814391a3 --- /dev/null +++ b/styles/bootstrap/fine-uploader/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2013-present, Widen Enterprises, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/styles/bootstrap/fine-uploader/continue.gif b/styles/bootstrap/fine-uploader/continue.gif new file mode 100644 index 000000000..303b7fbdc Binary files /dev/null and b/styles/bootstrap/fine-uploader/continue.gif differ diff --git a/styles/bootstrap/fine-uploader/dnd.js b/styles/bootstrap/fine-uploader/dnd.js new file mode 100644 index 000000000..100061705 --- /dev/null +++ b/styles/bootstrap/fine-uploader/dnd.js @@ -0,0 +1,1093 @@ +// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com +(function(global) { + var qq = function(element) { + "use strict"; + return { + hide: function() { + element.style.display = "none"; + return this; + }, + attach: function(type, fn) { + if (element.addEventListener) { + element.addEventListener(type, fn, false); + } else if (element.attachEvent) { + element.attachEvent("on" + type, fn); + } + return function() { + qq(element).detach(type, fn); + }; + }, + detach: function(type, fn) { + if (element.removeEventListener) { + element.removeEventListener(type, fn, false); + } else if (element.attachEvent) { + element.detachEvent("on" + type, fn); + } + return this; + }, + contains: function(descendant) { + if (!descendant) { + return false; + } + if (element === descendant) { + return true; + } + if (element.contains) { + return element.contains(descendant); + } else { + return !!(descendant.compareDocumentPosition(element) & 8); + } + }, + insertBefore: function(elementB) { + elementB.parentNode.insertBefore(element, elementB); + return this; + }, + remove: function() { + element.parentNode.removeChild(element); + return this; + }, + css: function(styles) { + if (element.style == null) { + throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!"); + } + if (styles.opacity != null) { + if (typeof element.style.opacity !== "string" && typeof element.filters !== "undefined") { + styles.filter = "alpha(opacity=" + Math.round(100 * styles.opacity) + ")"; + } + } + qq.extend(element.style, styles); + return this; + }, + hasClass: function(name, considerParent) { + var re = new RegExp("(^| )" + name + "( |$)"); + return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className)); + }, + addClass: function(name) { + if (!qq(element).hasClass(name)) { + element.className += " " + name; + } + return this; + }, + removeClass: function(name) { + var re = new RegExp("(^| )" + name + "( |$)"); + element.className = element.className.replace(re, " ").replace(/^\s+|\s+$/g, ""); + return this; + }, + getByClass: function(className, first) { + var candidates, result = []; + if (first && element.querySelector) { + return element.querySelector("." + className); + } else if (element.querySelectorAll) { + return element.querySelectorAll("." + className); + } + candidates = element.getElementsByTagName("*"); + qq.each(candidates, function(idx, val) { + if (qq(val).hasClass(className)) { + result.push(val); + } + }); + return first ? result[0] : result; + }, + getFirstByClass: function(className) { + return qq(element).getByClass(className, true); + }, + children: function() { + var children = [], child = element.firstChild; + while (child) { + if (child.nodeType === 1) { + children.push(child); + } + child = child.nextSibling; + } + return children; + }, + setText: function(text) { + element.innerText = text; + element.textContent = text; + return this; + }, + clearText: function() { + return qq(element).setText(""); + }, + hasAttribute: function(attrName) { + var attrVal; + if (element.hasAttribute) { + if (!element.hasAttribute(attrName)) { + return false; + } + return /^false$/i.exec(element.getAttribute(attrName)) == null; + } else { + attrVal = element[attrName]; + if (attrVal === undefined) { + return false; + } + return /^false$/i.exec(attrVal) == null; + } + } + }; + }; + (function() { + "use strict"; + qq.canvasToBlob = function(canvas, mime, quality) { + return qq.dataUriToBlob(canvas.toDataURL(mime, quality)); + }; + qq.dataUriToBlob = function(dataUri) { + var arrayBuffer, byteString, createBlob = function(data, mime) { + var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder, blobBuilder = BlobBuilder && new BlobBuilder(); + if (blobBuilder) { + blobBuilder.append(data); + return blobBuilder.getBlob(mime); + } else { + return new Blob([ data ], { + type: mime + }); + } + }, intArray, mimeString; + if (dataUri.split(",")[0].indexOf("base64") >= 0) { + byteString = atob(dataUri.split(",")[1]); + } else { + byteString = decodeURI(dataUri.split(",")[1]); + } + mimeString = dataUri.split(",")[0].split(":")[1].split(";")[0]; + arrayBuffer = new ArrayBuffer(byteString.length); + intArray = new Uint8Array(arrayBuffer); + qq.each(byteString, function(idx, character) { + intArray[idx] = character.charCodeAt(0); + }); + return createBlob(arrayBuffer, mimeString); + }; + qq.log = function(message, level) { + if (window.console) { + if (!level || level === "info") { + window.console.log(message); + } else { + if (window.console[level]) { + window.console[level](message); + } else { + window.console.log("<" + level + "> " + message); + } + } + } + }; + qq.isObject = function(variable) { + return variable && !variable.nodeType && Object.prototype.toString.call(variable) === "[object Object]"; + }; + qq.isFunction = function(variable) { + return typeof variable === "function"; + }; + qq.isArray = function(value) { + return Object.prototype.toString.call(value) === "[object Array]" || value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer; + }; + qq.isItemList = function(maybeItemList) { + return Object.prototype.toString.call(maybeItemList) === "[object DataTransferItemList]"; + }; + qq.isNodeList = function(maybeNodeList) { + return Object.prototype.toString.call(maybeNodeList) === "[object NodeList]" || maybeNodeList.item && maybeNodeList.namedItem; + }; + qq.isString = function(maybeString) { + return Object.prototype.toString.call(maybeString) === "[object String]"; + }; + qq.trimStr = function(string) { + if (String.prototype.trim) { + return string.trim(); + } + return string.replace(/^\s+|\s+$/g, ""); + }; + qq.format = function(str) { + var args = Array.prototype.slice.call(arguments, 1), newStr = str, nextIdxToReplace = newStr.indexOf("{}"); + qq.each(args, function(idx, val) { + var strBefore = newStr.substring(0, nextIdxToReplace), strAfter = newStr.substring(nextIdxToReplace + 2); + newStr = strBefore + val + strAfter; + nextIdxToReplace = newStr.indexOf("{}", nextIdxToReplace + val.length); + if (nextIdxToReplace < 0) { + return false; + } + }); + return newStr; + }; + qq.isFile = function(maybeFile) { + return window.File && Object.prototype.toString.call(maybeFile) === "[object File]"; + }; + qq.isFileList = function(maybeFileList) { + return window.FileList && Object.prototype.toString.call(maybeFileList) === "[object FileList]"; + }; + qq.isFileOrInput = function(maybeFileOrInput) { + return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput); + }; + qq.isInput = function(maybeInput, notFile) { + var evaluateType = function(type) { + var normalizedType = type.toLowerCase(); + if (notFile) { + return normalizedType !== "file"; + } + return normalizedType === "file"; + }; + if (window.HTMLInputElement) { + if (Object.prototype.toString.call(maybeInput) === "[object HTMLInputElement]") { + if (maybeInput.type && evaluateType(maybeInput.type)) { + return true; + } + } + } + if (maybeInput.tagName) { + if (maybeInput.tagName.toLowerCase() === "input") { + if (maybeInput.type && evaluateType(maybeInput.type)) { + return true; + } + } + } + return false; + }; + qq.isBlob = function(maybeBlob) { + if (window.Blob && Object.prototype.toString.call(maybeBlob) === "[object Blob]") { + return true; + } + }; + qq.isXhrUploadSupported = function() { + var input = document.createElement("input"); + input.type = "file"; + return input.multiple !== undefined && typeof File !== "undefined" && typeof FormData !== "undefined" && typeof qq.createXhrInstance().upload !== "undefined"; + }; + qq.createXhrInstance = function() { + if (window.XMLHttpRequest) { + return new XMLHttpRequest(); + } + try { + return new ActiveXObject("MSXML2.XMLHTTP.3.0"); + } catch (error) { + qq.log("Neither XHR or ActiveX are supported!", "error"); + return null; + } + }; + qq.isFolderDropSupported = function(dataTransfer) { + return dataTransfer.items && dataTransfer.items.length > 0 && dataTransfer.items[0].webkitGetAsEntry; + }; + qq.isFileChunkingSupported = function() { + return !qq.androidStock() && qq.isXhrUploadSupported() && (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined); + }; + qq.sliceBlob = function(fileOrBlob, start, end) { + var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice; + return slicer.call(fileOrBlob, start, end); + }; + qq.arrayBufferToHex = function(buffer) { + var bytesAsHex = "", bytes = new Uint8Array(buffer); + qq.each(bytes, function(idx, byt) { + var byteAsHexStr = byt.toString(16); + if (byteAsHexStr.length < 2) { + byteAsHexStr = "0" + byteAsHexStr; + } + bytesAsHex += byteAsHexStr; + }); + return bytesAsHex; + }; + qq.readBlobToHex = function(blob, startOffset, length) { + var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length), fileReader = new FileReader(), promise = new qq.Promise(); + fileReader.onload = function() { + promise.success(qq.arrayBufferToHex(fileReader.result)); + }; + fileReader.onerror = promise.failure; + fileReader.readAsArrayBuffer(initialBlob); + return promise; + }; + qq.extend = function(first, second, extendNested) { + qq.each(second, function(prop, val) { + if (extendNested && qq.isObject(val)) { + if (first[prop] === undefined) { + first[prop] = {}; + } + qq.extend(first[prop], val, true); + } else { + first[prop] = val; + } + }); + return first; + }; + qq.override = function(target, sourceFn) { + var super_ = {}, source = sourceFn(super_); + qq.each(source, function(srcPropName, srcPropVal) { + if (target[srcPropName] !== undefined) { + super_[srcPropName] = target[srcPropName]; + } + target[srcPropName] = srcPropVal; + }); + return target; + }; + qq.indexOf = function(arr, elt, from) { + if (arr.indexOf) { + return arr.indexOf(elt, from); + } + from = from || 0; + var len = arr.length; + if (from < 0) { + from += len; + } + for (;from < len; from += 1) { + if (arr.hasOwnProperty(from) && arr[from] === elt) { + return from; + } + } + return -1; + }; + qq.getUniqueId = function() { + return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) { + var r = Math.random() * 16 | 0, v = c == "x" ? r : r & 3 | 8; + return v.toString(16); + }); + }; + qq.ie = function() { + return navigator.userAgent.indexOf("MSIE") !== -1 || navigator.userAgent.indexOf("Trident") !== -1; + }; + qq.ie7 = function() { + return navigator.userAgent.indexOf("MSIE 7") !== -1; + }; + qq.ie8 = function() { + return navigator.userAgent.indexOf("MSIE 8") !== -1; + }; + qq.ie10 = function() { + return navigator.userAgent.indexOf("MSIE 10") !== -1; + }; + qq.ie11 = function() { + return qq.ie() && navigator.userAgent.indexOf("rv:11") !== -1; + }; + qq.edge = function() { + return navigator.userAgent.indexOf("Edge") >= 0; + }; + qq.safari = function() { + return navigator.vendor !== undefined && navigator.vendor.indexOf("Apple") !== -1; + }; + qq.chrome = function() { + return navigator.vendor !== undefined && navigator.vendor.indexOf("Google") !== -1; + }; + qq.opera = function() { + return navigator.vendor !== undefined && navigator.vendor.indexOf("Opera") !== -1; + }; + qq.firefox = function() { + return !qq.edge() && !qq.ie11() && navigator.userAgent.indexOf("Mozilla") !== -1 && navigator.vendor !== undefined && navigator.vendor === ""; + }; + qq.windows = function() { + return navigator.platform === "Win32"; + }; + qq.android = function() { + return navigator.userAgent.toLowerCase().indexOf("android") !== -1; + }; + qq.androidStock = function() { + return qq.android() && navigator.userAgent.toLowerCase().indexOf("chrome") < 0; + }; + qq.ios6 = function() { + return qq.ios() && navigator.userAgent.indexOf(" OS 6_") !== -1; + }; + qq.ios7 = function() { + return qq.ios() && navigator.userAgent.indexOf(" OS 7_") !== -1; + }; + qq.ios8 = function() { + return qq.ios() && navigator.userAgent.indexOf(" OS 8_") !== -1; + }; + qq.ios800 = function() { + return qq.ios() && navigator.userAgent.indexOf(" OS 8_0 ") !== -1; + }; + qq.ios = function() { + return navigator.userAgent.indexOf("iPad") !== -1 || navigator.userAgent.indexOf("iPod") !== -1 || navigator.userAgent.indexOf("iPhone") !== -1; + }; + qq.iosChrome = function() { + return qq.ios() && navigator.userAgent.indexOf("CriOS") !== -1; + }; + qq.iosSafari = function() { + return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf("Safari") !== -1; + }; + qq.iosSafariWebView = function() { + return qq.ios() && !qq.iosChrome() && !qq.iosSafari(); + }; + qq.preventDefault = function(e) { + if (e.preventDefault) { + e.preventDefault(); + } else { + e.returnValue = false; + } + }; + qq.toElement = function() { + var div = document.createElement("div"); + return function(html) { + div.innerHTML = html; + var element = div.firstChild; + div.removeChild(element); + return element; + }; + }(); + qq.each = function(iterableItem, callback) { + var keyOrIndex, retVal; + if (iterableItem) { + if (window.Storage && iterableItem.constructor === window.Storage) { + for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) { + retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex))); + if (retVal === false) { + break; + } + } + } else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) { + for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) { + retVal = callback(keyOrIndex, iterableItem[keyOrIndex]); + if (retVal === false) { + break; + } + } + } else if (qq.isString(iterableItem)) { + for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) { + retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex)); + if (retVal === false) { + break; + } + } + } else { + for (keyOrIndex in iterableItem) { + if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) { + retVal = callback(keyOrIndex, iterableItem[keyOrIndex]); + if (retVal === false) { + break; + } + } + } + } + } + }; + qq.bind = function(oldFunc, context) { + if (qq.isFunction(oldFunc)) { + var args = Array.prototype.slice.call(arguments, 2); + return function() { + var newArgs = qq.extend([], args); + if (arguments.length) { + newArgs = newArgs.concat(Array.prototype.slice.call(arguments)); + } + return oldFunc.apply(context, newArgs); + }; + } + throw new Error("first parameter must be a function!"); + }; + qq.obj2url = function(obj, temp, prefixDone) { + var uristrings = [], prefix = "&", add = function(nextObj, i) { + var nextTemp = temp ? /\[\]$/.test(temp) ? temp : temp + "[" + i + "]" : i; + if (nextTemp !== "undefined" && i !== "undefined") { + uristrings.push(typeof nextObj === "object" ? qq.obj2url(nextObj, nextTemp, true) : Object.prototype.toString.call(nextObj) === "[object Function]" ? encodeURIComponent(nextTemp) + "=" + encodeURIComponent(nextObj()) : encodeURIComponent(nextTemp) + "=" + encodeURIComponent(nextObj)); + } + }; + if (!prefixDone && temp) { + prefix = /\?/.test(temp) ? /\?$/.test(temp) ? "" : "&" : "?"; + uristrings.push(temp); + uristrings.push(qq.obj2url(obj)); + } else if (Object.prototype.toString.call(obj) === "[object Array]" && typeof obj !== "undefined") { + qq.each(obj, function(idx, val) { + add(val, idx); + }); + } else if (typeof obj !== "undefined" && obj !== null && typeof obj === "object") { + qq.each(obj, function(prop, val) { + add(val, prop); + }); + } else { + uristrings.push(encodeURIComponent(temp) + "=" + encodeURIComponent(obj)); + } + if (temp) { + return uristrings.join(prefix); + } else { + return uristrings.join(prefix).replace(/^&/, "").replace(/%20/g, "+"); + } + }; + qq.obj2FormData = function(obj, formData, arrayKeyName) { + if (!formData) { + formData = new FormData(); + } + qq.each(obj, function(key, val) { + key = arrayKeyName ? arrayKeyName + "[" + key + "]" : key; + if (qq.isObject(val)) { + qq.obj2FormData(val, formData, key); + } else if (qq.isFunction(val)) { + formData.append(key, val()); + } else { + formData.append(key, val); + } + }); + return formData; + }; + qq.obj2Inputs = function(obj, form) { + var input; + if (!form) { + form = document.createElement("form"); + } + qq.obj2FormData(obj, { + append: function(key, val) { + input = document.createElement("input"); + input.setAttribute("name", key); + input.setAttribute("value", val); + form.appendChild(input); + } + }); + return form; + }; + qq.parseJson = function(json) { + if (window.JSON && qq.isFunction(JSON.parse)) { + return JSON.parse(json); + } else { + return eval("(" + json + ")"); + } + }; + qq.getExtension = function(filename) { + var extIdx = filename.lastIndexOf(".") + 1; + if (extIdx > 0) { + return filename.substr(extIdx, filename.length - extIdx); + } + }; + qq.getFilename = function(blobOrFileInput) { + if (qq.isInput(blobOrFileInput)) { + return blobOrFileInput.value.replace(/.*(\/|\\)/, ""); + } else if (qq.isFile(blobOrFileInput)) { + if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) { + return blobOrFileInput.fileName; + } + } + return blobOrFileInput.name; + }; + qq.DisposeSupport = function() { + var disposers = []; + return { + dispose: function() { + var disposer; + do { + disposer = disposers.shift(); + if (disposer) { + disposer(); + } + } while (disposer); + }, + attach: function() { + var args = arguments; + this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1))); + }, + addDisposer: function(disposeFunction) { + disposers.push(disposeFunction); + } + }; + }; + })(); + (function() { + "use strict"; + if (typeof define === "function" && define.amd) { + define(function() { + return qq; + }); + } else if (typeof module !== "undefined" && module.exports) { + module.exports = qq; + } else { + global.qq = qq; + } + })(); + qq.version = "5.12.0"; + qq.supportedFeatures = function() { + "use strict"; + var supportsUploading, supportsUploadingBlobs, supportsFileDrop, supportsAjaxFileUploading, supportsFolderDrop, supportsChunking, supportsResume, supportsUploadViaPaste, supportsUploadCors, supportsDeleteFileXdr, supportsDeleteFileCorsXhr, supportsDeleteFileCors, supportsFolderSelection, supportsImagePreviews, supportsUploadProgress; + function testSupportsFileInputElement() { + var supported = true, tempInput; + try { + tempInput = document.createElement("input"); + tempInput.type = "file"; + qq(tempInput).hide(); + if (tempInput.disabled) { + supported = false; + } + } catch (ex) { + supported = false; + } + return supported; + } + function isChrome21OrHigher() { + return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/) !== undefined; + } + function isChrome14OrHigher() { + return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/) !== undefined; + } + function isCrossOriginXhrSupported() { + if (window.XMLHttpRequest) { + var xhr = qq.createXhrInstance(); + return xhr.withCredentials !== undefined; + } + return false; + } + function isXdrSupported() { + return window.XDomainRequest !== undefined; + } + function isCrossOriginAjaxSupported() { + if (isCrossOriginXhrSupported()) { + return true; + } + return isXdrSupported(); + } + function isFolderSelectionSupported() { + return document.createElement("input").webkitdirectory !== undefined; + } + function isLocalStorageSupported() { + try { + return !!window.localStorage && qq.isFunction(window.localStorage.setItem); + } catch (error) { + return false; + } + } + function isDragAndDropSupported() { + var span = document.createElement("span"); + return ("draggable" in span || "ondragstart" in span && "ondrop" in span) && !qq.android() && !qq.ios(); + } + supportsUploading = testSupportsFileInputElement(); + supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported(); + supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock(); + supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported(); + supportsFolderDrop = supportsFileDrop && isChrome21OrHigher(); + supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported(); + supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported(); + supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher(); + supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading); + supportsDeleteFileCorsXhr = isCrossOriginXhrSupported(); + supportsDeleteFileXdr = isXdrSupported(); + supportsDeleteFileCors = isCrossOriginAjaxSupported(); + supportsFolderSelection = isFolderSelectionSupported(); + supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined; + supportsUploadProgress = function() { + if (supportsAjaxFileUploading) { + return !qq.androidStock() && !qq.iosChrome(); + } + return false; + }(); + return { + ajaxUploading: supportsAjaxFileUploading, + blobUploading: supportsUploadingBlobs, + canDetermineSize: supportsAjaxFileUploading, + chunking: supportsChunking, + deleteFileCors: supportsDeleteFileCors, + deleteFileCorsXdr: supportsDeleteFileXdr, + deleteFileCorsXhr: supportsDeleteFileCorsXhr, + dialogElement: !!window.HTMLDialogElement, + fileDrop: supportsFileDrop, + folderDrop: supportsFolderDrop, + folderSelection: supportsFolderSelection, + imagePreviews: supportsImagePreviews, + imageValidation: supportsImagePreviews, + itemSizeValidation: supportsAjaxFileUploading, + pause: supportsChunking, + progressBar: supportsUploadProgress, + resume: supportsResume, + scaling: supportsImagePreviews && supportsUploadingBlobs, + tiffPreviews: qq.safari(), + unlimitedScaledImageSize: !qq.ios(), + uploading: supportsUploading, + uploadCors: supportsUploadCors, + uploadCustomHeaders: supportsAjaxFileUploading, + uploadNonMultipart: supportsAjaxFileUploading, + uploadViaPaste: supportsUploadViaPaste + }; + }(); + qq.isGenericPromise = function(maybePromise) { + "use strict"; + return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then)); + }; + qq.Promise = function() { + "use strict"; + var successArgs, failureArgs, successCallbacks = [], failureCallbacks = [], doneCallbacks = [], state = 0; + qq.extend(this, { + then: function(onSuccess, onFailure) { + if (state === 0) { + if (onSuccess) { + successCallbacks.push(onSuccess); + } + if (onFailure) { + failureCallbacks.push(onFailure); + } + } else if (state === -1) { + onFailure && onFailure.apply(null, failureArgs); + } else if (onSuccess) { + onSuccess.apply(null, successArgs); + } + return this; + }, + done: function(callback) { + if (state === 0) { + doneCallbacks.push(callback); + } else { + callback.apply(null, failureArgs === undefined ? successArgs : failureArgs); + } + return this; + }, + success: function() { + state = 1; + successArgs = arguments; + if (successCallbacks.length) { + qq.each(successCallbacks, function(idx, callback) { + callback.apply(null, successArgs); + }); + } + if (doneCallbacks.length) { + qq.each(doneCallbacks, function(idx, callback) { + callback.apply(null, successArgs); + }); + } + return this; + }, + failure: function() { + state = -1; + failureArgs = arguments; + if (failureCallbacks.length) { + qq.each(failureCallbacks, function(idx, callback) { + callback.apply(null, failureArgs); + }); + } + if (doneCallbacks.length) { + qq.each(doneCallbacks, function(idx, callback) { + callback.apply(null, failureArgs); + }); + } + return this; + } + }); + }; + qq.DragAndDrop = function(o) { + "use strict"; + var options, HIDE_ZONES_EVENT_NAME = "qq-hidezones", HIDE_BEFORE_ENTER_ATTR = "qq-hide-dropzone", uploadDropZones = [], droppedFiles = [], disposeSupport = new qq.DisposeSupport(); + options = { + dropZoneElements: [], + allowMultipleItems: true, + classes: { + dropActive: null + }, + callbacks: new qq.DragAndDrop.callbacks() + }; + qq.extend(options, o, true); + function uploadDroppedFiles(files, uploadDropZone) { + var filesAsArray = Array.prototype.slice.call(files); + options.callbacks.dropLog("Grabbed " + files.length + " dropped files."); + uploadDropZone.dropDisabled(false); + options.callbacks.processingDroppedFilesComplete(filesAsArray, uploadDropZone.getElement()); + } + function traverseFileTree(entry) { + var parseEntryPromise = new qq.Promise(); + if (entry.isFile) { + entry.file(function(file) { + var name = entry.name, fullPath = entry.fullPath, indexOfNameInFullPath = fullPath.indexOf(name); + fullPath = fullPath.substr(0, indexOfNameInFullPath); + if (fullPath.charAt(0) === "/") { + fullPath = fullPath.substr(1); + } + file.qqPath = fullPath; + droppedFiles.push(file); + parseEntryPromise.success(); + }, function(fileError) { + options.callbacks.dropLog("Problem parsing '" + entry.fullPath + "'. FileError code " + fileError.code + ".", "error"); + parseEntryPromise.failure(); + }); + } else if (entry.isDirectory) { + getFilesInDirectory(entry).then(function allEntriesRead(entries) { + var entriesLeft = entries.length; + qq.each(entries, function(idx, entry) { + traverseFileTree(entry).done(function() { + entriesLeft -= 1; + if (entriesLeft === 0) { + parseEntryPromise.success(); + } + }); + }); + if (!entries.length) { + parseEntryPromise.success(); + } + }, function readFailure(fileError) { + options.callbacks.dropLog("Problem parsing '" + entry.fullPath + "'. FileError code " + fileError.code + ".", "error"); + parseEntryPromise.failure(); + }); + } + return parseEntryPromise; + } + function getFilesInDirectory(entry, reader, accumEntries, existingPromise) { + var promise = existingPromise || new qq.Promise(), dirReader = reader || entry.createReader(); + dirReader.readEntries(function readSuccess(entries) { + var newEntries = accumEntries ? accumEntries.concat(entries) : entries; + if (entries.length) { + setTimeout(function() { + getFilesInDirectory(entry, dirReader, newEntries, promise); + }, 0); + } else { + promise.success(newEntries); + } + }, promise.failure); + return promise; + } + function handleDataTransfer(dataTransfer, uploadDropZone) { + var pendingFolderPromises = [], handleDataTransferPromise = new qq.Promise(); + options.callbacks.processingDroppedFiles(); + uploadDropZone.dropDisabled(true); + if (dataTransfer.files.length > 1 && !options.allowMultipleItems) { + options.callbacks.processingDroppedFilesComplete([]); + options.callbacks.dropError("tooManyFilesError", ""); + uploadDropZone.dropDisabled(false); + handleDataTransferPromise.failure(); + } else { + droppedFiles = []; + if (qq.isFolderDropSupported(dataTransfer)) { + qq.each(dataTransfer.items, function(idx, item) { + var entry = item.webkitGetAsEntry(); + if (entry) { + if (entry.isFile) { + droppedFiles.push(item.getAsFile()); + } else { + pendingFolderPromises.push(traverseFileTree(entry).done(function() { + pendingFolderPromises.pop(); + if (pendingFolderPromises.length === 0) { + handleDataTransferPromise.success(); + } + })); + } + } + }); + } else { + droppedFiles = dataTransfer.files; + } + if (pendingFolderPromises.length === 0) { + handleDataTransferPromise.success(); + } + } + return handleDataTransferPromise; + } + function setupDropzone(dropArea) { + var dropZone = new qq.UploadDropZone({ + HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME, + element: dropArea, + onEnter: function(e) { + qq(dropArea).addClass(options.classes.dropActive); + e.stopPropagation(); + }, + onLeaveNotDescendants: function(e) { + qq(dropArea).removeClass(options.classes.dropActive); + }, + onDrop: function(e) { + handleDataTransfer(e.dataTransfer, dropZone).then(function() { + uploadDroppedFiles(droppedFiles, dropZone); + }, function() { + options.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.", "error"); + }); + } + }); + disposeSupport.addDisposer(function() { + dropZone.dispose(); + }); + qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide(); + uploadDropZones.push(dropZone); + return dropZone; + } + function isFileDrag(dragEvent) { + var fileDrag; + qq.each(dragEvent.dataTransfer.types, function(key, val) { + if (val === "Files") { + fileDrag = true; + return false; + } + }); + return fileDrag; + } + function leavingDocumentOut(e) { + if (qq.firefox()) { + return !e.relatedTarget; + } + if (qq.safari()) { + return e.x < 0 || e.y < 0; + } + return e.x === 0 && e.y === 0; + } + function setupDragDrop() { + var dropZones = options.dropZoneElements, maybeHideDropZones = function() { + setTimeout(function() { + qq.each(dropZones, function(idx, dropZone) { + qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide(); + qq(dropZone).removeClass(options.classes.dropActive); + }); + }, 10); + }; + qq.each(dropZones, function(idx, dropZone) { + var uploadDropZone = setupDropzone(dropZone); + if (dropZones.length && qq.supportedFeatures.fileDrop) { + disposeSupport.attach(document, "dragenter", function(e) { + if (!uploadDropZone.dropDisabled() && isFileDrag(e)) { + qq.each(dropZones, function(idx, dropZone) { + if (dropZone instanceof HTMLElement && qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) { + qq(dropZone).css({ + display: "block" + }); + } + }); + } + }); + } + }); + disposeSupport.attach(document, "dragleave", function(e) { + if (leavingDocumentOut(e)) { + maybeHideDropZones(); + } + }); + disposeSupport.attach(qq(document).children()[0], "mouseenter", function(e) { + maybeHideDropZones(); + }); + disposeSupport.attach(document, "drop", function(e) { + e.preventDefault(); + maybeHideDropZones(); + }); + disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones); + } + setupDragDrop(); + qq.extend(this, { + setupExtraDropzone: function(element) { + options.dropZoneElements.push(element); + setupDropzone(element); + }, + removeDropzone: function(element) { + var i, dzs = options.dropZoneElements; + for (i in dzs) { + if (dzs[i] === element) { + return dzs.splice(i, 1); + } + } + }, + dispose: function() { + disposeSupport.dispose(); + qq.each(uploadDropZones, function(idx, dropZone) { + dropZone.dispose(); + }); + } + }); + }; + qq.DragAndDrop.callbacks = function() { + "use strict"; + return { + processingDroppedFiles: function() {}, + processingDroppedFilesComplete: function(files, targetEl) {}, + dropError: function(code, errorSpecifics) { + qq.log("Drag & drop error code '" + code + " with these specifics: '" + errorSpecifics + "'", "error"); + }, + dropLog: function(message, level) { + qq.log(message, level); + } + }; + }; + qq.UploadDropZone = function(o) { + "use strict"; + var disposeSupport = new qq.DisposeSupport(), options, element, preventDrop, dropOutsideDisabled; + options = { + element: null, + onEnter: function(e) {}, + onLeave: function(e) {}, + onLeaveNotDescendants: function(e) {}, + onDrop: function(e) {} + }; + qq.extend(options, o); + element = options.element; + function dragoverShouldBeCanceled() { + return qq.safari() || qq.firefox() && qq.windows(); + } + function disableDropOutside(e) { + if (!dropOutsideDisabled) { + if (dragoverShouldBeCanceled) { + disposeSupport.attach(document, "dragover", function(e) { + e.preventDefault(); + }); + } else { + disposeSupport.attach(document, "dragover", function(e) { + if (e.dataTransfer) { + e.dataTransfer.dropEffect = "none"; + e.preventDefault(); + } + }); + } + dropOutsideDisabled = true; + } + } + function isValidFileDrag(e) { + if (!qq.supportedFeatures.fileDrop) { + return false; + } + var effectTest, dt = e.dataTransfer, isSafari = qq.safari(); + effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== "none"; + return dt && effectTest && (dt.files || !isSafari && dt.types.contains && dt.types.contains("Files")); + } + function isOrSetDropDisabled(isDisabled) { + if (isDisabled !== undefined) { + preventDrop = isDisabled; + } + return preventDrop; + } + function triggerHidezonesEvent() { + var hideZonesEvent; + function triggerUsingOldApi() { + hideZonesEvent = document.createEvent("Event"); + hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true); + } + if (window.CustomEvent) { + try { + hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME); + } catch (err) { + triggerUsingOldApi(); + } + } else { + triggerUsingOldApi(); + } + document.dispatchEvent(hideZonesEvent); + } + function attachEvents() { + disposeSupport.attach(element, "dragover", function(e) { + if (!isValidFileDrag(e)) { + return; + } + var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed; + if (effect === "move" || effect === "linkMove") { + e.dataTransfer.dropEffect = "move"; + } else { + e.dataTransfer.dropEffect = "copy"; + } + e.stopPropagation(); + e.preventDefault(); + }); + disposeSupport.attach(element, "dragenter", function(e) { + if (!isOrSetDropDisabled()) { + if (!isValidFileDrag(e)) { + return; + } + options.onEnter(e); + } + }); + disposeSupport.attach(element, "dragleave", function(e) { + if (!isValidFileDrag(e)) { + return; + } + options.onLeave(e); + var relatedTarget = document.elementFromPoint(e.clientX, e.clientY); + if (qq(this).contains(relatedTarget)) { + return; + } + options.onLeaveNotDescendants(e); + }); + disposeSupport.attach(element, "drop", function(e) { + if (!isOrSetDropDisabled()) { + if (!isValidFileDrag(e)) { + return; + } + e.preventDefault(); + e.stopPropagation(); + options.onDrop(e); + triggerHidezonesEvent(); + } + }); + } + disableDropOutside(); + attachEvents(); + qq.extend(this, { + dropDisabled: function(isDisabled) { + return isOrSetDropDisabled(isDisabled); + }, + dispose: function() { + disposeSupport.dispose(); + }, + getElement: function() { + return element; + } + }); + }; +})(window); +//# sourceMappingURL=dnd.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/dnd.js.map b/styles/bootstrap/fine-uploader/dnd.js.map new file mode 100644 index 000000000..dce774d90 --- /dev/null +++ b/styles/bootstrap/fine-uploader/dnd.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/dnd.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","intArray","mimeString","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","testSupportsFileInputElement","supported","tempInput","disabled","ex","isChrome21OrHigher","match","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","DragAndDrop","o","options","HIDE_ZONES_EVENT_NAME","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","droppedFiles","disposeSupport","dropZoneElements","allowMultipleItems","classes","dropActive","callbacks","uploadDroppedFiles","files","uploadDropZone","filesAsArray","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","entry","parseEntryPromise","file","fullPath","indexOfNameInFullPath","qqPath","fileError","code","isDirectory","getFilesInDirectory","allEntriesRead","entries","entriesLeft","readFailure","reader","accumEntries","existingPromise","dirReader","createReader","readEntries","readSuccess","newEntries","setTimeout","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","dropError","getAsFile","pop","setupDropzone","dropArea","dropZone","UploadDropZone","onEnter","stopPropagation","onLeaveNotDescendants","onDrop","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","x","y","setupDragDrop","dropZones","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","splice","targetEl","errorSpecifics","preventDrop","dropOutsideDisabled","onLeave","dragoverShouldBeCanceled","disableDropOutside","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","triggerHidezonesEvent","hideZonesEvent","triggerUsingOldApi","createEvent","initEvent","CustomEvent","err","dispatchEvent","attachEvents","effect","elementFromPoint","clientX","clientY"],"mappings":";CAAA,SAAUA;ICEV,IAAIC,KAAK,SAASC;QACd;QAEA;YACIC,MAAM;gBACFD,QAAQE,MAAMC,UAAU;gBACxB,OAAOC;;YAIXC,QAAQ,SAASC,MAAMC;gBACnB,IAAIP,QAAQQ,kBAAkB;oBAC1BR,QAAQQ,iBAAiBF,MAAMC,IAAI;uBAChC,IAAIP,QAAQS,aAAa;oBAC5BT,QAAQS,YAAY,OAAOH,MAAMC;;gBAErC,OAAO;oBACHR,GAAGC,SAASU,OAAOJ,MAAMC;;;YAIjCG,QAAQ,SAASJ,MAAMC;gBACnB,IAAIP,QAAQW,qBAAqB;oBAC7BX,QAAQW,oBAAoBL,MAAMC,IAAI;uBACnC,IAAIP,QAAQS,aAAa;oBAC5BT,QAAQY,YAAY,OAAON,MAAMC;;gBAErC,OAAOH;;YAGXS,UAAU,SAASC;gBAKf,KAAKA,YAAY;oBACb,OAAO;;gBAIX,IAAId,YAAYc,YAAY;oBACxB,OAAO;;gBAGX,IAAId,QAAQa,UAAU;oBAClB,OAAOb,QAAQa,SAASC;uBACrB;oBAEH,UAAUA,WAAWC,wBAAwBf,WAAW;;;YAOhEgB,cAAc,SAASC;gBACnBA,SAASC,WAAWF,aAAahB,SAASiB;gBAC1C,OAAOb;;YAGXe,QAAQ;gBACJnB,QAAQkB,WAAWE,YAAYpB;gBAC/B,OAAOI;;YAOXiB,KAAK,SAASC;gBAEV,IAAItB,QAAQE,SAAS,MAAM;oBACvB,MAAM,IAAIH,GAAGwB,MAAM;;gBAIvB,IAAID,OAAOE,WAAW,MAAM;oBACxB,WAAWxB,QAAQE,MAAMsB,YAAY,mBAAoBxB,QAAe,YAAM,aAAa;wBACvFsB,OAAOG,SAAS,mBAAmBC,KAAKC,MAAM,MAAML,OAAOE,WAAW;;;gBAG9EzB,GAAG6B,OAAO5B,QAAQE,OAAOoB;gBAEzB,OAAOlB;;YAGXyB,UAAU,SAASC,MAAMC;gBACrB,IAAIC,KAAK,IAAIC,OAAO,UAAUH,OAAO;gBACrC,OAAOE,GAAGE,KAAKlC,QAAQmC,iBAAiBJ,kBAAkBC,GAAGE,KAAKlC,QAAQkB,WAAWiB;;YAGzFC,UAAU,SAASN;gBACf,KAAK/B,GAAGC,SAAS6B,SAASC,OAAO;oBAC7B9B,QAAQmC,aAAa,MAAML;;gBAE/B,OAAO1B;;YAGXiC,aAAa,SAASP;gBAClB,IAAIE,KAAK,IAAIC,OAAO,UAAUH,OAAO;gBACrC9B,QAAQmC,YAAYnC,QAAQmC,UAAUG,QAAQN,IAAI,KAAKM,QAAQ,cAAc;gBAC7E,OAAOlC;;YAGXmC,YAAY,SAASJ,WAAWK;gBAC5B,IAAIC,YACAC;gBAEJ,IAAIF,SAASxC,QAAQ2C,eAAe;oBAChC,OAAO3C,QAAQ2C,cAAc,MAAMR;uBAElC,IAAInC,QAAQ4C,kBAAkB;oBAC/B,OAAO5C,QAAQ4C,iBAAiB,MAAMT;;gBAG1CM,aAAazC,QAAQ6C,qBAAqB;gBAE1C9C,GAAG+C,KAAKL,YAAY,SAASM,KAAKC;oBAC9B,IAAIjD,GAAGiD,KAAKnB,SAASM,YAAY;wBAC7BO,OAAOO,KAAKD;;;gBAGpB,OAAOR,QAAQE,OAAO,KAAKA;;YAG/BQ,iBAAiB,SAASf;gBACtB,OAAOpC,GAAGC,SAASuC,WAAWJ,WAAW;;YAG7CgB,UAAU;gBACN,IAAIA,eACAC,QAAQpD,QAAQqD;gBAEpB,OAAOD,OAAO;oBACV,IAAIA,MAAME,aAAa,GAAG;wBACtBH,SAASF,KAAKG;;oBAElBA,QAAQA,MAAMG;;gBAGlB,OAAOJ;;YAGXK,SAAS,SAASC;gBACdzD,QAAQ0D,YAAYD;gBACpBzD,QAAQ2D,cAAcF;gBACtB,OAAOrD;;YAGXwD,WAAW;gBACP,OAAO7D,GAAGC,SAASwD,QAAQ;;YAK/BK,cAAc,SAASC;gBACnB,IAAIC;gBAEJ,IAAI/D,QAAQ6D,cAAc;oBAEtB,KAAK7D,QAAQ6D,aAAaC,WAAW;wBACjC,OAAO;;oBAIX,OAAO,WAAaE,KAAKhE,QAAQiE,aAAaH,cAAc;uBAE3D;oBACDC,UAAU/D,QAAQ8D;oBAElB,IAAIC,YAAYG,WAAW;wBACvB,OAAO;;oBAIX,OAAO,WAAaF,KAAKD,YAAY;;;;;KAMpD;QACG;QAEAhE,GAAGoE,eAAe,SAASC,QAAQC,MAAMC;YACrC,OAAOvE,GAAGwE,cAAcH,OAAOI,UAAUH,MAAMC;;QAGnDvE,GAAGwE,gBAAgB,SAASE;YACxB,IAAIC,aAAaC,YACbC,aAAa,SAASC,MAAMR;gBACxB,IAAIS,cAAcC,OAAOD,eACjBC,OAAOC,qBACPD,OAAOE,kBACPF,OAAOG,eACXC,cAAcL,eAAe,IAAIA;gBAErC,IAAIK,aAAa;oBACbA,YAAYC,OAAOP;oBACnB,OAAOM,YAAYE,QAAQhB;uBAE1B;oBACD,OAAO,IAAIiB,OAAMT;wBAAQvE,MAAM+D;;;eAGvCkB,UAAUC;YAGd,IAAIf,QAAQgB,MAAM,KAAK,GAAGC,QAAQ,aAAa,GAAG;gBAC9Cf,aAAagB,KAAKlB,QAAQgB,MAAM,KAAK;mBAEpC;gBACDd,aAAaiB,UAAUnB,QAAQgB,MAAM,KAAK;;YAI9CD,aAAaf,QAAQgB,MAAM,KAAK,GAC3BA,MAAM,KAAK,GACXA,MAAM,KAAK;YAGhBf,cAAc,IAAImB,YAAYlB,WAAWmB;YACzCP,WAAW,IAAIQ,WAAWrB;YAC1B3E,GAAG+C,KAAK6B,YAAY,SAAS5B,KAAKiD;gBAC9BT,SAASxC,OAAOiD,UAAUC,WAAW;;YAGzC,OAAOrB,WAAWF,aAAac;;QAGnCzF,GAAGmG,MAAM,SAASC,SAASC;YACvB,IAAIrB,OAAOsB,SAAS;gBAChB,KAAKD,SAASA,UAAU,QAAQ;oBAC5BrB,OAAOsB,QAAQH,IAAIC;uBAGvB;oBACI,IAAIpB,OAAOsB,QAAQD,QAAQ;wBACvBrB,OAAOsB,QAAQD,OAAOD;2BAErB;wBACDpB,OAAOsB,QAAQH,IAAI,MAAME,QAAQ,OAAOD;;;;;QAMxDpG,GAAGuG,WAAW,SAASC;YACnB,OAAOA,aAAaA,SAASjD,YAAYkD,OAAOC,UAAUC,SAASC,KAAKJ,cAAc;;QAG1FxG,GAAG6G,aAAa,SAASL;YACrB,cAAc,aAAe;;QASjCxG,GAAG8G,UAAU,SAASC;YAClB,OAAON,OAAOC,UAAUC,SAASC,KAAKG,WAAW,oBAC5CA,SAAS/B,OAAOc,eAAeiB,MAAMC,UAAUD,MAAMC,OAAOC,gBAAgBnB;;QAIrF9F,GAAGkH,aAAa,SAASC;YACrB,OAAOV,OAAOC,UAAUC,SAASC,KAAKO,mBAAmB;;QAK7DnH,GAAGoH,aAAa,SAASC;YACrB,OAAOZ,OAAOC,UAAUC,SAASC,KAAKS,mBAAmB,uBAGpDA,cAAcC,QAAQD,cAAcE;;QAG7CvH,GAAGwH,WAAW,SAASC;YACnB,OAAOhB,OAAOC,UAAUC,SAASC,KAAKa,iBAAiB;;QAG3DzH,GAAG0H,UAAU,SAASC;YAClB,IAAIC,OAAOlB,UAAUmB,MAAM;gBACvB,OAAOF,OAAOE;;YAGlB,OAAOF,OAAOpF,QAAQ,cAAc;;QAOxCvC,GAAG8H,SAAS,SAASC;YAEjB,IAAIC,OAAQC,MAAMvB,UAAUwB,MAAMtB,KAAKuB,WAAW,IAC9CC,SAASL,KACTM,mBAAmBD,OAAOzC,QAAQ;YAEtC3F,GAAG+C,KAAKiF,MAAM,SAAShF,KAAKC;gBACxB,IAAIqF,YAAYF,OAAOG,UAAU,GAAGF,mBAChCG,WAAWJ,OAAOG,UAAUF,mBAAmB;gBAEnDD,SAASE,YAAYrF,MAAMuF;gBAC3BH,mBAAmBD,OAAOzC,QAAQ,MAAM0C,mBAAmBpF,IAAI8C;gBAG/D,IAAIsC,mBAAmB,GAAG;oBACtB,OAAO;;;YAIf,OAAOD;;QAGXpI,GAAGyI,SAAS,SAASC;YACjB,OAAO1D,OAAO2D,QAAQlC,OAAOC,UAAUC,SAASC,KAAK8B,eAAe;;QAGxE1I,GAAG4I,aAAa,SAASC;YACrB,OAAO7D,OAAO8D,YAAYrC,OAAOC,UAAUC,SAASC,KAAKiC,mBAAmB;;QAGhF7I,GAAG+I,gBAAgB,SAASC;YACxB,OAAOhJ,GAAGyI,OAAOO,qBAAqBhJ,GAAGiJ,QAAQD;;QAGrDhJ,GAAGiJ,UAAU,SAASC,YAAYC;YAC9B,IAAIC,eAAe,SAAS7I;gBACxB,IAAI8I,iBAAiB9I,KAAK+I;gBAE1B,IAAIH,SAAS;oBACT,OAAOE,mBAAmB;;gBAG9B,OAAOA,mBAAmB;;YAG9B,IAAIrE,OAAOuE,kBAAkB;gBACzB,IAAI9C,OAAOC,UAAUC,SAASC,KAAKsC,gBAAgB,6BAA6B;oBAC5E,IAAIA,WAAW3I,QAAQ6I,aAAaF,WAAW3I,OAAO;wBAClD,OAAO;;;;YAInB,IAAI2I,WAAWM,SAAS;gBACpB,IAAIN,WAAWM,QAAQF,kBAAkB,SAAS;oBAC9C,IAAIJ,WAAW3I,QAAQ6I,aAAaF,WAAW3I,OAAO;wBAClD,OAAO;;;;YAKnB,OAAO;;QAGXP,GAAGyJ,SAAS,SAASC;YACjB,IAAI1E,OAAOO,QAAQkB,OAAOC,UAAUC,SAASC,KAAK8C,eAAe,iBAAiB;gBAC9E,OAAO;;;QAIf1J,GAAG2J,uBAAuB;YACtB,IAAIC,QAAQC,SAASC,cAAc;YACnCF,MAAMrJ,OAAO;YAEb,OACIqJ,MAAMG,aAAa5F,oBACRwE,SAAS,sBACTqB,aAAa,sBACZhK,GAAGiK,oBAAqBC,WAAW;;QAIvDlK,GAAGiK,oBAAoB;YACnB,IAAIjF,OAAOmF,gBAAgB;gBACvB,OAAO,IAAIA;;YAGf;gBACI,OAAO,IAAIC,cAAc;cAE7B,OAAOC;gBACHrK,GAAGmG,IAAI,yCAAyC;gBAChD,OAAO;;;QAIfnG,GAAGsK,wBAAwB,SAASC;YAChC,OAAOA,aAAaC,SAChBD,aAAaC,MAAMzE,SAAS,KAC5BwE,aAAaC,MAAM,GAAGC;;QAG9BzK,GAAG0K,0BAA0B;YACzB,QAAQ1K,GAAG2K,kBACP3K,GAAG2J,2BACFhB,KAAKjC,UAAUwB,UAAU/D,aAAawE,KAAKjC,UAAUkE,gBAAgBzG,aAAawE,KAAKjC,UAAUmE,aAAa1G;;QAGvHnE,GAAG8K,YAAY,SAASC,YAAYC,OAAOC;YACvC,IAAIC,SAASH,WAAW7C,SAAS6C,WAAWF,YAAYE,WAAWH;YAEnE,OAAOM,OAAOtE,KAAKmE,YAAYC,OAAOC;;QAG1CjL,GAAGmL,mBAAmB,SAASnE;YAC3B,IAAIoE,aAAa,IACbC,QAAQ,IAAIrF,WAAWgB;YAE3BhH,GAAG+C,KAAKsI,OAAO,SAASrI,KAAKsI;gBACzB,IAAIC,eAAeD,IAAI3E,SAAS;gBAEhC,IAAI4E,aAAaxF,SAAS,GAAG;oBACzBwF,eAAe,MAAMA;;gBAGzBH,cAAcG;;YAGlB,OAAOH;;QAGXpL,GAAGwL,gBAAgB,SAASC,MAAMC,aAAa3F;YAC3C,IAAI4F,cAAc3L,GAAG8K,UAAUW,MAAMC,aAAaA,cAAc3F,SAC5D6F,aAAa,IAAIC,cACjBC,UAAU,IAAI9L,GAAG+L;YAErBH,WAAWI,SAAS;gBAChBF,QAAQG,QAAQjM,GAAGmL,iBAAiBS,WAAWjJ;;YAGnDiJ,WAAWM,UAAUJ,QAAQK;YAE7BP,WAAWQ,kBAAkBT;YAE7B,OAAOG;;QAGX9L,GAAG6B,SAAS,SAASY,OAAO4J,QAAQC;YAChCtM,GAAG+C,KAAKsJ,QAAQ,SAASE,MAAMtJ;gBAC3B,IAAIqJ,gBAAgBtM,GAAGuG,SAAStD,MAAM;oBAClC,IAAIR,MAAM8J,UAAUpI,WAAW;wBAC3B1B,MAAM8J;;oBAEVvM,GAAG6B,OAAOY,MAAM8J,OAAOtJ,KAAK;uBAE3B;oBACDR,MAAM8J,QAAQtJ;;;YAItB,OAAOR;;QAaXzC,GAAGwM,WAAW,SAASC,QAAQC;YAC3B,IAAIC,aACAC,SAASF,SAASC;YAEtB3M,GAAG+C,KAAK6J,QAAQ,SAASC,aAAaC;gBAClC,IAAIL,OAAOI,iBAAiB1I,WAAW;oBACnCwI,OAAOE,eAAeJ,OAAOI;;gBAGjCJ,OAAOI,eAAeC;;YAG1B,OAAOL;;QAMXzM,GAAG2F,UAAU,SAASoH,KAAKC,KAAKC;YAC5B,IAAIF,IAAIpH,SAAS;gBACb,OAAOoH,IAAIpH,QAAQqH,KAAKC;;YAG5BA,OAAOA,QAAQ;YACf,IAAIC,MAAMH,IAAIhH;YAEd,IAAIkH,OAAO,GAAG;gBACVA,QAAQC;;YAGZ,MAAOD,OAAOC,KAAKD,QAAQ,GAAG;gBAC1B,IAAIF,IAAII,eAAeF,SAASF,IAAIE,UAAUD,KAAK;oBAC/C,OAAOC;;;YAGf,QAAQ;;QAIZjN,GAAGoN,cAAc;YACb,OAAO,uCAAuC7K,QAAQ,SAAS,SAAS8K;gBAEpE,IAAIC,IAAI3L,KAAK4L,WAAW,KAAK,GAAGC,IAAIH,KAAK,MAAMC,IAAKA,IAAI,IAAM;gBAC9D,OAAOE,EAAE7G,SAAS;;;QAM1B3G,GAAGyN,KAAK;YACJ,OAAOC,UAAUC,UAAUhI,QAAQ,aAAa,KAC5C+H,UAAUC,UAAUhI,QAAQ,gBAAgB;;QAGpD3F,GAAG4N,MAAM;YACL,OAAOF,UAAUC,UAAUhI,QAAQ,eAAe;;QAGtD3F,GAAG6N,MAAM;YACL,OAAOH,UAAUC,UAAUhI,QAAQ,eAAe;;QAGtD3F,GAAG8N,OAAO;YACN,OAAOJ,UAAUC,UAAUhI,QAAQ,gBAAgB;;QAGvD3F,GAAG+N,OAAO;YACN,OAAO/N,GAAGyN,QAAQC,UAAUC,UAAUhI,QAAQ,cAAc;;QAGhE3F,GAAGgO,OAAO;YACN,OAAON,UAAUC,UAAUhI,QAAQ,WAAW;;QAGlD3F,GAAGiO,SAAS;YACR,OAAOP,UAAUQ,WAAW/J,aAAauJ,UAAUQ,OAAOvI,QAAQ,cAAc;;QAGpF3F,GAAGmO,SAAS;YACR,OAAOT,UAAUQ,WAAW/J,aAAauJ,UAAUQ,OAAOvI,QAAQ,eAAe;;QAGrF3F,GAAGoO,QAAQ;YACP,OAAOV,UAAUQ,WAAW/J,aAAauJ,UAAUQ,OAAOvI,QAAQ,cAAc;;QAGpF3F,GAAGqO,UAAU;YACT,QAASrO,GAAGgO,WAAWhO,GAAG+N,UAAUL,UAAUC,UAAUhI,QAAQ,gBAAgB,KAAK+H,UAAUQ,WAAW/J,aAAauJ,UAAUQ,WAAW;;QAGhJlO,GAAGsO,UAAU;YACT,OAAOZ,UAAUa,aAAa;;QAGlCvO,GAAGwO,UAAU;YACT,OAAOd,UAAUC,UAAUrE,cAAc3D,QAAQ,gBAAgB;;QAKrE3F,GAAG2K,eAAe;YACd,OAAO3K,GAAGwO,aAAad,UAAUC,UAAUrE,cAAc3D,QAAQ,YAAY;;QAGjF3F,GAAGyO,OAAO;YACN,OAAOzO,GAAG0O,SAAShB,UAAUC,UAAUhI,QAAQ,eAAe;;QAGlE3F,GAAG2O,OAAO;YACN,OAAO3O,GAAG0O,SAAShB,UAAUC,UAAUhI,QAAQ,eAAe;;QAGlE3F,GAAG4O,OAAO;YACN,OAAO5O,GAAG0O,SAAShB,UAAUC,UAAUhI,QAAQ,eAAe;;QAIlE3F,GAAG6O,SAAS;YACR,OAAO7O,GAAG0O,SAAShB,UAAUC,UAAUhI,QAAQ,iBAAiB;;QAGpE3F,GAAG0O,MAAM;YAEL,OAAOhB,UAAUC,UAAUhI,QAAQ,aAAa,KACzC+H,UAAUC,UAAUhI,QAAQ,aAAa,KACzC+H,UAAUC,UAAUhI,QAAQ,eAAe;;QAGtD3F,GAAG8O,YAAY;YACX,OAAO9O,GAAG0O,SAAShB,UAAUC,UAAUhI,QAAQ,cAAc;;QAGjE3F,GAAG+O,YAAY;YACX,OAAO/O,GAAG0O,UAAU1O,GAAG8O,eAAepB,UAAUC,UAAUhI,QAAQ,eAAe;;QAGrF3F,GAAGgP,mBAAmB;YAClB,OAAOhP,GAAG0O,UAAU1O,GAAG8O,gBAAgB9O,GAAG+O;;QAM9C/O,GAAGiP,iBAAiB,SAASC;YACzB,IAAIA,EAAED,gBAAgB;gBAClBC,EAAED;mBACC;gBACHC,EAAEC,cAAc;;;QAQxBnP,GAAGoP,YAAa;YACZ,IAAIC,MAAMxF,SAASC,cAAc;YACjC,OAAO,SAASwF;gBACZD,IAAIE,YAAYD;gBAChB,IAAIrP,UAAUoP,IAAI/L;gBAClB+L,IAAIhO,YAAYpB;gBAChB,OAAOA;;;QAKfD,GAAG+C,OAAO,SAASyM,cAAcC;YAC7B,IAAIC,YAAYC;YAEhB,IAAIH,cAAc;gBAEd,IAAIxK,OAAO4K,WAAWJ,aAAavI,gBAAgBjC,OAAO4K,SAAS;oBAC/D,KAAKF,aAAa,GAAGA,aAAaF,aAAazJ,QAAQ2J,cAAc;wBACjEC,SAASF,SAASD,aAAaK,IAAIH,aAAaF,aAAaM,QAAQN,aAAaK,IAAIH;wBACtF,IAAIC,WAAW,OAAO;4BAClB;;;uBAMP,IAAI3P,GAAG8G,QAAQ0I,iBAAiBxP,GAAGkH,WAAWsI,iBAAiBxP,GAAGoH,WAAWoI,eAAe;oBAC7F,KAAKE,aAAa,GAAGA,aAAaF,aAAazJ,QAAQ2J,cAAc;wBACjEC,SAASF,SAASC,YAAYF,aAAaE;wBAC3C,IAAIC,WAAW,OAAO;4BAClB;;;uBAIP,IAAI3P,GAAGwH,SAASgI,eAAe;oBAChC,KAAKE,aAAa,GAAGA,aAAaF,aAAazJ,QAAQ2J,cAAc;wBACjEC,SAASF,SAASC,YAAYF,aAAaO,OAAOL;wBAClD,IAAIC,WAAW,OAAO;4BAClB;;;uBAIP;oBACD,KAAKD,cAAcF,cAAc;wBAC7B,IAAI/I,OAAOC,UAAUyG,eAAevG,KAAK4I,cAAcE,aAAa;4BAChEC,SAASF,SAASC,YAAYF,aAAaE;4BAC3C,IAAIC,WAAW,OAAO;gCAClB;;;;;;;QASxB3P,GAAGgQ,OAAO,SAASC,SAASC;YACxB,IAAIlQ,GAAG6G,WAAWoJ,UAAU;gBACxB,IAAIjI,OAAQC,MAAMvB,UAAUwB,MAAMtB,KAAKuB,WAAW;gBAElD,OAAO;oBACH,IAAIgI,UAAUnQ,GAAG6B,WAAWmG;oBAC5B,IAAIG,UAAUpC,QAAQ;wBAClBoK,UAAUA,QAAQC,OAAOnI,MAAMvB,UAAUwB,MAAMtB,KAAKuB;;oBAExD,OAAO8H,QAAQI,MAAMH,SAASC;;;YAItC,MAAM,IAAI3O,MAAM;;QAmBpBxB,GAAGsQ,UAAU,SAASC,KAAKC,MAAMC;YAE7B,IAAIC,iBACAC,SAAS,KACTC,MAAM,SAASC,SAASC;gBACpB,IAAIC,WAAWP,OACR,QAAQrO,KAAKqO,QACdA,OACAA,OAAO,MAAMM,IAAI,MACjBA;gBACN,IAAKC,aAAa,eAAiBD,MAAM,aAAc;oBACnDJ,WAAWxN,YACC2N,YAAY,WACd7Q,GAAGsQ,QAAQO,SAASE,UAAU,QAC7BtK,OAAOC,UAAUC,SAASC,KAAKiK,aAAa,sBAC7CG,mBAAmBD,YAAY,MAAMC,mBAAmBH,aACxDG,mBAAmBD,YAAY,MAAMC,mBAAmBH;;;YAK9E,KAAKJ,cAAcD,MAAM;gBACrBG,SAAU,KAAKxO,KAAKqO,QAAU,MAAMrO,KAAKqO,QAAS,KAAK,MAAM;gBAC7DE,WAAWxN,KAAKsN;gBAChBE,WAAWxN,KAAKlD,GAAGsQ,QAAQC;mBACxB,IAAK9J,OAAOC,UAAUC,SAASC,KAAK2J,SAAS,2BAA6BA,QAAQ,aAAc;gBACnGvQ,GAAG+C,KAAKwN,KAAK,SAASvN,KAAKC;oBACvB2N,IAAI3N,KAAKD;;mBAEV,WAAYuN,QAAQ,eAAiBA,QAAQ,eAAiBA,QAAQ,UAAW;gBACpFvQ,GAAG+C,KAAKwN,KAAK,SAAShE,MAAMtJ;oBACxB2N,IAAI3N,KAAKsJ;;mBAEV;gBACHmE,WAAWxN,KAAK8N,mBAAmBR,QAAQ,MAAMQ,mBAAmBT;;YAGxE,IAAIC,MAAM;gBACN,OAAOE,WAAWO,KAAKN;mBACpB;gBACH,OAAOD,WAAWO,KAAKN,QAClBpO,QAAQ,MAAM,IACdA,QAAQ,QAAQ;;;QAI7BvC,GAAGkR,eAAe,SAASX,KAAKY,UAAUC;YACtC,KAAKD,UAAU;gBACXA,WAAW,IAAInH;;YAGnBhK,GAAG+C,KAAKwN,KAAK,SAASV,KAAK5M;gBACvB4M,MAAMuB,eAAeA,eAAe,MAAMvB,MAAM,MAAMA;gBAEtD,IAAI7P,GAAGuG,SAAStD,MAAM;oBAClBjD,GAAGkR,aAAajO,KAAKkO,UAAUtB;uBAE9B,IAAI7P,GAAG6G,WAAW5D,MAAM;oBACzBkO,SAAS9L,OAAOwK,KAAK5M;uBAEpB;oBACDkO,SAAS9L,OAAOwK,KAAK5M;;;YAI7B,OAAOkO;;QAGXnR,GAAGqR,aAAa,SAASd,KAAKe;YAC1B,IAAI1H;YAEJ,KAAK0H,MAAM;gBACPA,OAAOzH,SAASC,cAAc;;YAGlC9J,GAAGkR,aAAaX;gBACZlL,QAAQ,SAASwK,KAAK5M;oBAClB2G,QAAQC,SAASC,cAAc;oBAC/BF,MAAM2H,aAAa,QAAQ1B;oBAC3BjG,MAAM2H,aAAa,SAAStO;oBAC5BqO,KAAKE,YAAY5H;;;YAIzB,OAAO0H;;QAOXtR,GAAGyR,YAAY,SAASC;YAEpB,IAAI1M,OAAO2M,QAAQ3R,GAAG6G,WAAW8K,KAAKC,QAAQ;gBAC1C,OAAOD,KAAKC,MAAMF;mBACf;gBACH,OAAOG,KAAK,MAAMH,OAAO;;;QAUjC1R,GAAG8R,eAAe,SAASC;YACvB,IAAIC,SAASD,SAASE,YAAY,OAAO;YAEzC,IAAID,SAAS,GAAG;gBACZ,OAAOD,SAASG,OAAOF,QAAQD,SAAShM,SAASiM;;;QAIzDhS,GAAGmS,cAAc,SAASC;YAGtB,IAAIpS,GAAGiJ,QAAQmJ,kBAAkB;gBAE7B,OAAOA,gBAAgBrL,MAAMxE,QAAQ,aAAa;mBAEjD,IAAIvC,GAAGyI,OAAO2J,kBAAkB;gBACjC,IAAIA,gBAAgBC,aAAa,QAAQD,gBAAgBC,aAAalO,WAAW;oBAC7E,OAAOiO,gBAAgBC;;;YAI/B,OAAOD,gBAAgBrQ;;QAM3B/B,GAAGsS,iBAAiB;YAChB,IAAIC;YAEJ;gBAEIC,SAAS;oBACL,IAAIC;oBACJ,GAAG;wBACCA,WAAWF,UAAUG;wBACrB,IAAID,UAAU;4BACVA;;6BAGDA;;gBAIXnS,QAAQ;oBACJ,IAAI0H,OAAOG;oBAEX9H,KAAKsS,YAAY3S,GAAGgI,KAAK,IAAI1H,OAAO+P,MAAMhQ,MAAM4H,MAAMvB,UAAUwB,MAAMtB,KAAKuB,WAAW;;gBAI1FwK,aAAa,SAASC;oBAClBL,UAAUrP,KAAK0P;;;;;KCt2B9B;QACG;QACA,WAAWC,WAAW,cAAcA,OAAOC,KAAK;YAC5CD,OAAO;gBACH,OAAO7S;;eAGV,WAAW+S,WAAW,eAAeA,OAAOC,SAAS;YACtDD,OAAOC,UAAUhT;eAEhB;YACDD,OAAOC,KAAKA;;;ICXpBA,GAAGiT,UAAU;ICAbjT,GAAGkT,oBAAqB;QACpB;QAEA,IAAIC,mBACAC,wBACAC,kBACAC,2BACAC,oBACAC,kBACAC,gBACAC,wBACAC,oBACAC,uBACAC,2BACAC,wBACAC,yBACAC,uBACAC;QAEJ,SAASC;YACL,IAAIC,YAAY,MACZC;YAEJ;gBACIA,YAAYvK,SAASC,cAAc;gBACnCsK,UAAU7T,OAAO;gBACjBP,GAAGoU,WAAWlU;gBAEd,IAAIkU,UAAUC,UAAU;oBACpBF,YAAY;;cAGpB,OAAOG;gBACHH,YAAY;;YAGhB,OAAOA;;QAIX,SAASI;YACL,QAAQvU,GAAGmO,YAAYnO,GAAGoO,YACtBV,UAAUC,UAAU6G,MAAM,2CAA2CrQ;;QAI7E,SAASsQ;YACL,QAAQzU,GAAGmO,YAAYnO,GAAGoO,YACtBV,UAAUC,UAAU6G,MAAM,2CAA2CrQ;;QAI7E,SAASuQ;YACL,IAAI1P,OAAOmF,gBAAgB;gBACvB,IAAIwK,MAAM3U,GAAGiK;gBAGb,OAAO0K,IAAIC,oBAAoBzQ;;YAGnC,OAAO;;QAIX,SAAS0Q;YACL,OAAO7P,OAAO8P,mBAAmB3Q;;QAKrC,SAAS4Q;YACL,IAAIL,6BAA6B;gBAC7B,OAAO;;YAGX,OAAOG;;QAGX,SAASG;YAEL,OAAOnL,SAASC,cAAc,SAASmL,oBAAoB9Q;;QAG/D,SAAS+Q;YACL;gBACI,SAASlQ,OAAOmQ,gBAEZnV,GAAG6G,WAAW7B,OAAOmQ,aAAaC;cAE1C,OAAO/K;gBAEH,OAAO;;;QAIf,SAASgL;YACL,IAAIC,OAAOzL,SAASC,cAAc;YAElC,QAAQ,eAAewL,QAAS,iBAAiBA,QAAQ,YAAYA,UAChEtV,GAAGwO,cAAcxO,GAAG0O;;QAG7ByE,oBAAoBe;QAEpBZ,4BAA4BH,qBAAqBnT,GAAG2J;QAEpDyJ,yBAAyBE,8BAA8BtT,GAAG2K;QAE1D0I,mBAAmBC,6BAA6B+B;QAEhD9B,qBAAqBF,oBAAoBkB;QAEzCf,mBAAmBF,6BAA6BtT,GAAG0K;QAEnD+I,iBAAiBH,6BAA6BE,oBAAoB0B;QAElExB,yBAAyBJ,6BAA6BmB;QAEtDd,qBAAqBR,sBAAsBnO,OAAOuQ,gBAAgBpR,aAAamP;QAE/EO,4BAA4Ba;QAE5Bd,wBAAwBiB;QAExBf,yBAAyBiB;QAEzBhB,0BAA0BiB;QAE1BhB,wBAAwBV,6BAA6BtO,OAAO6G,eAAe1H;QAE3E8P,yBAA0B;YACtB,IAAIX,2BAA2B;gBAC3B,QAAQtT,GAAG2K,mBAAmB3K,GAAG8O;;YAErC,OAAO;;QAGX;YACI0G,eAAelC;YACfmC,eAAerC;YACfsC,kBAAkBpC;YAClBqC,UAAUnC;YACVoC,gBAAgB9B;YAChB+B,mBAAmBjC;YACnBkC,mBAAmBjC;YACnBkC,iBAAiB/Q,OAAOgR;YACxBC,UAAU5C;YACV6C,YAAY3C;YACZ4C,iBAAiBpC;YACjBqC,eAAepC;YACfqC,iBAAiBrC;YACjBsC,oBAAoBhD;YACpBiD,OAAO/C;YACPgD,aAAavC;YACbwC,QAAQhD;YACRiD,SAAS1C,yBAAyBZ;YAClCuD,cAAc3W,GAAGiO;YACjB2I,2BAA2B5W,GAAG0O;YAC9BmI,WAAW1D;YACX2D,YAAYnD;YACZoD,qBAAqBzD;YACrB0D,oBAAoB1D;YACpB2D,gBAAgBvD;;;IChKxB1T,GAAGkX,mBAAmB,SAASC;QAC3B;QACA,UAAUA,gBAAgBA,aAAaC,QAAQpX,GAAG6G,WAAWsQ,aAAaC;;IAG9EpX,GAAG+L,UAAU;QACT;QAEA,IAAIsL,aAAaC,aACbC,uBACAC,uBACAC,oBACAC,QAAQ;QAEZ1X,GAAG6B,OAAOxB;YACN+W,MAAM,SAASO,WAAWC;gBACtB,IAAIF,UAAU,GAAG;oBACb,IAAIC,WAAW;wBACXJ,iBAAiBrU,KAAKyU;;oBAE1B,IAAIC,WAAW;wBACXJ,iBAAiBtU,KAAK0U;;uBAGzB,IAAIF,WAAW,GAAG;oBACnBE,aAAaA,UAAUvH,MAAM,MAAMiH;uBAElC,IAAIK,WAAW;oBAChBA,UAAUtH,MAAM,MAAMgH;;gBAG1B,OAAOhX;;YAGXwX,MAAM,SAASpI;gBACX,IAAIiI,UAAU,GAAG;oBACbD,cAAcvU,KAAKuM;uBAElB;oBACDA,SAASY,MAAM,MAAMiH,gBAAgBnT,YAAYkT,cAAcC;;gBAGnE,OAAOjX;;YAGX4L,SAAS;gBACLyL,QAAQ;gBACRL,cAAclP;gBAEd,IAAIoP,iBAAiBxR,QAAQ;oBACzB/F,GAAG+C,KAAKwU,kBAAkB,SAASvU,KAAKyM;wBACpCA,SAASY,MAAM,MAAMgH;;;gBAI7B,IAAII,cAAc1R,QAAQ;oBACtB/F,GAAG+C,KAAK0U,eAAe,SAASzU,KAAKyM;wBACjCA,SAASY,MAAM,MAAMgH;;;gBAI7B,OAAOhX;;YAGX8L,SAAS;gBACLuL,SAAS;gBACTJ,cAAcnP;gBAEd,IAAIqP,iBAAiBzR,QAAQ;oBACzB/F,GAAG+C,KAAKyU,kBAAkB,SAASxU,KAAKyM;wBACpCA,SAASY,MAAM,MAAMiH;;;gBAI7B,IAAIG,cAAc1R,QAAQ;oBACtB/F,GAAG+C,KAAK0U,eAAe,SAASzU,KAAKyM;wBACjCA,SAASY,MAAM,MAAMiH;;;gBAI7B,OAAOjX;;;;IClFnBL,GAAG8X,cAAc,SAASC;QACtB;QAEA,IAAIC,SACAC,wBAAwB,gBACxBC,yBAAyB,oBACzBC,sBACAC,mBACAC,iBAAiB,IAAIrY,GAAGsS;QAE5B0F;YACIM;YACAC,oBAAoB;YACpBC;gBACIC,YAAY;;YAEhBC,WAAW,IAAI1Y,GAAG8X,YAAYY;;QAGlC1Y,GAAG6B,OAAOmW,SAASD,GAAG;QAEtB,SAASY,mBAAmBC,OAAOC;YAE/B,IAAIC,eAAe7Q,MAAMvB,UAAUwB,MAAMtB,KAAKgS;YAE9CZ,QAAQU,UAAUK,QAAQ,aAAaH,MAAM7S,SAAS;YACtD8S,eAAeG,aAAa;YAC5BhB,QAAQU,UAAUO,+BAA+BH,cAAcD,eAAeK;;QAGlF,SAASC,iBAAiBC;YACtB,IAAIC,oBAAoB,IAAIrZ,GAAG+L;YAE/B,IAAIqN,MAAM3Q,QAAQ;gBACd2Q,MAAME,KAAK,SAASA;oBAChB,IAAIvX,OAAOqX,MAAMrX,MACbwX,WAAWH,MAAMG,UACjBC,wBAAwBD,SAAS5T,QAAQ5D;oBAG7CwX,WAAWA,SAASrH,OAAO,GAAGsH;oBAG9B,IAAID,SAASxJ,OAAO,OAAO,KAAK;wBAC5BwJ,WAAWA,SAASrH,OAAO;;oBAG/BoH,KAAKG,SAASF;oBACdnB,aAAalV,KAAKoW;oBAClBD,kBAAkBpN;mBAEtB,SAASyN;oBACL1B,QAAQU,UAAUK,QAAQ,sBAAsBK,MAAMG,WAAW,wBAAwBG,UAAUC,OAAO,KAAK;oBAC/GN,kBAAkBlN;;mBAGrB,IAAIiN,MAAMQ,aAAa;gBACxBC,oBAAoBT,OAAOhC,KACvB,SAAS0C,eAAeC;oBACpB,IAAIC,cAAcD,QAAQhU;oBAE1B/F,GAAG+C,KAAKgX,SAAS,SAAS/W,KAAKoW;wBAC3BD,iBAAiBC,OAAOvB,KAAK;4BACzBmC,eAAe;4BAEf,IAAIA,gBAAgB,GAAG;gCACnBX,kBAAkBpN;;;;oBAK9B,KAAK8N,QAAQhU,QAAQ;wBACjBsT,kBAAkBpN;;mBAI1B,SAASgO,YAAYP;oBACjB1B,QAAQU,UAAUK,QAAQ,sBAAsBK,MAAMG,WAAW,wBAAwBG,UAAUC,OAAO,KAAK;oBAC/GN,kBAAkBlN;;;YAK9B,OAAOkN;;QAIX,SAASQ,oBAAoBT,OAAOc,QAAQC,cAAcC;YACtD,IAAItO,UAAUsO,mBAAmB,IAAIpa,GAAG+L,WACpCsO,YAAYH,UAAUd,MAAMkB;YAEhCD,UAAUE,YACN,SAASC,YAAYT;gBACjB,IAAIU,aAAaN,eAAeA,aAAa/J,OAAO2J,WAAWA;gBAE/D,IAAIA,QAAQhU,QAAQ;oBAChB2U,WAAW;wBACPb,oBAAoBT,OAAOiB,WAAWI,YAAY3O;uBACnD;uBAEF;oBACDA,QAAQG,QAAQwO;;eAIxB3O,QAAQK;YAGZ,OAAOL;;QAGX,SAAS6O,mBAAmBpQ,cAAcsO;YACtC,IAAI+B,4BACAC,4BAA4B,IAAI7a,GAAG+L;YAEvCiM,QAAQU,UAAUoC;YAClBjC,eAAeG,aAAa;YAE5B,IAAIzO,aAAaqO,MAAM7S,SAAS,MAAMiS,QAAQO,oBAAoB;gBAC9DP,QAAQU,UAAUO;gBAClBjB,QAAQU,UAAUqC,UAAU,qBAAqB;gBACjDlC,eAAeG,aAAa;gBAC5B6B,0BAA0B1O;mBAEzB;gBACDiM;gBAEA,IAAIpY,GAAGsK,sBAAsBC,eAAe;oBACxCvK,GAAG+C,KAAKwH,aAAaC,OAAO,SAASxH,KAAKsE;wBACtC,IAAI8R,QAAQ9R,KAAKmD;wBAEjB,IAAI2O,OAAO;4BAEP,IAAIA,MAAM3Q,QAAQ;gCACd2P,aAAalV,KAAKoE,KAAK0T;mCAGtB;gCACDJ,sBAAsB1X,KAAKiW,iBAAiBC,OAAOvB,KAAK;oCACpD+C,sBAAsBK;oCACtB,IAAIL,sBAAsB7U,WAAW,GAAG;wCACpC8U,0BAA0B5O;;;;;;uBAO7C;oBACDmM,eAAe7N,aAAaqO;;gBAGhC,IAAIgC,sBAAsB7U,WAAW,GAAG;oBACpC8U,0BAA0B5O;;;YAIlC,OAAO4O;;QAGX,SAASK,cAAcC;YACnB,IAAIC,WAAW,IAAIpb,GAAGqb;gBAClBpD,uBAAuBA;gBACvBhY,SAASkb;gBACTG,SAAS,SAASpM;oBACdlP,GAAGmb,UAAU9Y,SAAS2V,QAAQQ,QAAQC;oBACtCvJ,EAAEqM;;gBAENC,uBAAuB,SAAStM;oBAC5BlP,GAAGmb,UAAU7Y,YAAY0V,QAAQQ,QAAQC;;gBAE7CgD,QAAQ,SAASvM;oBACbyL,mBAAmBzL,EAAE3E,cAAc6Q,UAAUhE,KACzC;wBACIuB,mBAAmBP,cAAcgD;uBAErC;wBACIpD,QAAQU,UAAUK,QAAQ,uEAAuE;;;;YAMjHV,eAAe1F,YAAY;gBACvByI,SAAS5I;;YAGbxS,GAAGmb,UAAUrX,aAAaoU,2BAA2BlY,GAAGmb,UAAUjb;YAElEiY,gBAAgBjV,KAAKkY;YAErB,OAAOA;;QAGX,SAASM,WAAWC;YAChB,IAAIC;YAEJ5b,GAAG+C,KAAK4Y,UAAUpR,aAAasR,OAAO,SAAShM,KAAK5M;gBAChD,IAAIA,QAAQ,SAAS;oBACjB2Y,WAAW;oBACX,OAAO;;;YAIf,OAAOA;;QAWX,SAASE,mBAAmB5M;YACxB,IAAIlP,GAAGqO,WAAW;gBACd,QAAQa,EAAE6M;;YAGd,IAAI/b,GAAGiO,UAAU;gBACb,OAAOiB,EAAE8M,IAAI,KAAK9M,EAAE+M,IAAI;;YAG5B,OAAO/M,EAAE8M,MAAM,KAAK9M,EAAE+M,MAAM;;QAGhC,SAASC;YACL,IAAIC,YAAYnE,QAAQM,kBAEpB8D,qBAAqB;gBACjB1B,WAAW;oBACP1a,GAAG+C,KAAKoZ,WAAW,SAASnZ,KAAKoY;wBAC7Bpb,GAAGob,UAAUtX,aAAaoU,2BAA2BlY,GAAGob,UAAUlb;wBAClEF,GAAGob,UAAU9Y,YAAY0V,QAAQQ,QAAQC;;mBAE9C;;YAGXzY,GAAG+C,KAAKoZ,WAAW,SAASnZ,KAAKoY;gBAC7B,IAAIvC,iBAAiBqC,cAAcE;gBAGnC,IAAIe,UAAUpW,UAAU/F,GAAGkT,kBAAkB+C,UAAU;oBACnDoC,eAAe/X,OAAOuJ,UAAU,aAAa,SAASqF;wBAClD,KAAK2J,eAAeG,kBAAkB0C,WAAWxM,IAAI;4BACjDlP,GAAG+C,KAAKoZ,WAAW,SAASnZ,KAAKoY;gCAG7B,IAAIA,oBAAoBiB,eACpBrc,GAAGob,UAAUtX,aAAaoU,yBAAyB;oCAEnDlY,GAAGob,UAAU9Z;wCAAKlB,SAAS;;;;;;;;YAQnDiY,eAAe/X,OAAOuJ,UAAU,aAAa,SAASqF;gBAClD,IAAI4M,mBAAmB5M,IAAI;oBACvBkN;;;YAOR/D,eAAe/X,OAAON,GAAG6J,UAAUzG,WAAW,IAAI,cAAc,SAAS8L;gBACrEkN;;YAGJ/D,eAAe/X,OAAOuJ,UAAU,QAAQ,SAASqF;gBAC7CA,EAAED;gBACFmN;;YAGJ/D,eAAe/X,OAAOuJ,UAAUoO,uBAAuBmE;;QAG3DF;QAEAlc,GAAG6B,OAAOxB;YACNic,oBAAoB,SAASrc;gBACzB+X,QAAQM,iBAAiBpV,KAAKjD;gBAC9Bib,cAAcjb;;YAGlBsc,gBAAgB,SAAStc;gBACrB,IAAI6Q,GACA0L,MAAMxE,QAAQM;gBAElB,KAAKxH,KAAK0L,KAAK;oBACX,IAAIA,IAAI1L,OAAO7Q,SAAS;wBACpB,OAAOuc,IAAIC,OAAO3L,GAAG;;;;YAKjC0B,SAAS;gBACL6F,eAAe7F;gBACfxS,GAAG+C,KAAKoV,iBAAiB,SAASnV,KAAKoY;oBACnCA,SAAS5I;;;;;IAMzBxS,GAAG8X,YAAYY,YAAY;QACvB;QAEA;YACIoC,wBAAwB;YACxB7B,gCAAgC,SAASL,OAAO8D;YAChD3B,WAAW,SAASpB,MAAMgD;gBACtB3c,GAAGmG,IAAI,6BAA6BwT,OAAO,6BAA6BgD,iBAAiB,KAAK;;YAElG5D,SAAS,SAAS3S,SAASC;gBACvBrG,GAAGmG,IAAIC,SAASC;;;;IAK5BrG,GAAGqb,iBAAiB,SAAStD;QACzB;QAEA,IAAIM,iBAAiB,IAAIrY,GAAGsS,kBACxB0F,SAAS/X,SAAS2c,aAAaC;QAEnC7E;YACI/X,SAAS;YACTqb,SAAS,SAASpM;YAClB4N,SAAS,SAAS5N;YAElBsM,uBAAuB,SAAStM;YAChCuM,QAAQ,SAASvM;;QAGrBlP,GAAG6B,OAAOmW,SAASD;QACnB9X,UAAU+X,QAAQ/X;QAElB,SAAS8c;YACL,OAAO/c,GAAGiO,YAAajO,GAAGqO,aAAarO,GAAGsO;;QAG9C,SAAS0O,mBAAmB9N;YAExB,KAAK2N,qBAAqB;gBAGtB,IAAIE,0BAA0B;oBAC1B1E,eAAe/X,OAAOuJ,UAAU,YAAY,SAASqF;wBACjDA,EAAED;;uBAEH;oBACHoJ,eAAe/X,OAAOuJ,UAAU,YAAY,SAASqF;wBACjD,IAAIA,EAAE3E,cAAc;4BAChB2E,EAAE3E,aAAa0S,aAAa;4BAC5B/N,EAAED;;;;gBAKd4N,sBAAsB;;;QAI9B,SAASK,gBAAgBhO;YAGrB,KAAKlP,GAAGkT,kBAAkB+C,UAAU;gBAChC,OAAO;;YAGX,IAAIkH,YAAYC,KAAKlO,EAAE3E,cAEvB8S,WAAWrd,GAAGiO;YAOdkP,aAAand,GAAGyN,QAAQzN,GAAGkT,kBAAkB+C,WAAW,OAAOmH,GAAGE,kBAAkB;YACpF,OAAOF,MAAMD,eAAeC,GAAGxE,UAAWyE,YAAYD,GAAGvB,MAAM/a,YAAYsc,GAAGvB,MAAM/a,SAAS;;QAGjG,SAASyc,oBAAoBC;YACzB,IAAIA,eAAerZ,WAAW;gBAC1ByY,cAAcY;;YAElB,OAAOZ;;QAGX,SAASa;YACL,IAAIC;YAEJ,SAASC;gBACLD,iBAAiB7T,SAAS+T,YAAY;gBACtCF,eAAeG,UAAU7F,QAAQC,uBAAuB,MAAM;;YAGlE,IAAIjT,OAAO8Y,aAAa;gBACpB;oBACIJ,iBAAiB,IAAII,YAAY9F,QAAQC;kBAE7C,OAAO8F;oBACHJ;;mBAGH;gBACDA;;YAGJ9T,SAASmU,cAAcN;;QAG3B,SAASO;YACL5F,eAAe/X,OAAOL,SAAS,YAAY,SAASiP;gBAChD,KAAKgO,gBAAgBhO,IAAI;oBACrB;;gBAKJ,IAAIgP,SAASle,GAAGyN,QAAQzN,GAAGkT,kBAAkB+C,WAAW,OAAO/G,EAAE3E,aAAa+S;gBAC9E,IAAIY,WAAW,UAAUA,WAAW,YAAY;oBAC5ChP,EAAE3E,aAAa0S,aAAa;uBACzB;oBACH/N,EAAE3E,aAAa0S,aAAa;;gBAGhC/N,EAAEqM;gBACFrM,EAAED;;YAGNoJ,eAAe/X,OAAOL,SAAS,aAAa,SAASiP;gBACjD,KAAKqO,uBAAuB;oBACxB,KAAKL,gBAAgBhO,IAAI;wBACrB;;oBAEJ8I,QAAQsD,QAAQpM;;;YAIxBmJ,eAAe/X,OAAOL,SAAS,aAAa,SAASiP;gBACjD,KAAKgO,gBAAgBhO,IAAI;oBACrB;;gBAGJ8I,QAAQ8E,QAAQ5N;gBAEhB,IAAI6M,gBAAgBlS,SAASsU,iBAAiBjP,EAAEkP,SAASlP,EAAEmP;gBAE3D,IAAIre,GAAGK,MAAMS,SAASib,gBAAgB;oBAClC;;gBAGJ/D,QAAQwD,sBAAsBtM;;YAGlCmJ,eAAe/X,OAAOL,SAAS,QAAQ,SAASiP;gBAC5C,KAAKqO,uBAAuB;oBACxB,KAAKL,gBAAgBhO,IAAI;wBACrB;;oBAGJA,EAAED;oBACFC,EAAEqM;oBACFvD,QAAQyD,OAAOvM;oBAEfuO;;;;QAKZT;QACAiB;QAEAje,GAAG6B,OAAOxB;YACN2Y,cAAc,SAASwE;gBACnB,OAAOD,oBAAoBC;;YAG/BhL,SAAS;gBACL6F,eAAe7F;;YAGnB0G,YAAY;gBACR,OAAOjZ;;;;GN3eY+E","file":"dnd.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/*globals qq, document, CustomEvent*/\nqq.DragAndDrop = function(o) {\n \"use strict\";\n\n var options,\n HIDE_ZONES_EVENT_NAME = \"qq-hidezones\",\n HIDE_BEFORE_ENTER_ATTR = \"qq-hide-dropzone\",\n uploadDropZones = [],\n droppedFiles = [],\n disposeSupport = new qq.DisposeSupport();\n\n options = {\n dropZoneElements: [],\n allowMultipleItems: true,\n classes: {\n dropActive: null\n },\n callbacks: new qq.DragAndDrop.callbacks()\n };\n\n qq.extend(options, o, true);\n\n function uploadDroppedFiles(files, uploadDropZone) {\n // We need to convert the `FileList` to an actual `Array` to avoid iteration issues\n var filesAsArray = Array.prototype.slice.call(files);\n\n options.callbacks.dropLog(\"Grabbed \" + files.length + \" dropped files.\");\n uploadDropZone.dropDisabled(false);\n options.callbacks.processingDroppedFilesComplete(filesAsArray, uploadDropZone.getElement());\n }\n\n function traverseFileTree(entry) {\n var parseEntryPromise = new qq.Promise();\n\n if (entry.isFile) {\n entry.file(function(file) {\n var name = entry.name,\n fullPath = entry.fullPath,\n indexOfNameInFullPath = fullPath.indexOf(name);\n\n // remove file name from full path string\n fullPath = fullPath.substr(0, indexOfNameInFullPath);\n\n // remove leading slash in full path string\n if (fullPath.charAt(0) === \"/\") {\n fullPath = fullPath.substr(1);\n }\n\n file.qqPath = fullPath;\n droppedFiles.push(file);\n parseEntryPromise.success();\n },\n function(fileError) {\n options.callbacks.dropLog(\"Problem parsing '\" + entry.fullPath + \"'. FileError code \" + fileError.code + \".\", \"error\");\n parseEntryPromise.failure();\n });\n }\n else if (entry.isDirectory) {\n getFilesInDirectory(entry).then(\n function allEntriesRead(entries) {\n var entriesLeft = entries.length;\n\n qq.each(entries, function(idx, entry) {\n traverseFileTree(entry).done(function() {\n entriesLeft -= 1;\n\n if (entriesLeft === 0) {\n parseEntryPromise.success();\n }\n });\n });\n\n if (!entries.length) {\n parseEntryPromise.success();\n }\n },\n\n function readFailure(fileError) {\n options.callbacks.dropLog(\"Problem parsing '\" + entry.fullPath + \"'. FileError code \" + fileError.code + \".\", \"error\");\n parseEntryPromise.failure();\n }\n );\n }\n\n return parseEntryPromise;\n }\n\n // Promissory. Guaranteed to read all files in the root of the passed directory.\n function getFilesInDirectory(entry, reader, accumEntries, existingPromise) {\n var promise = existingPromise || new qq.Promise(),\n dirReader = reader || entry.createReader();\n\n dirReader.readEntries(\n function readSuccess(entries) {\n var newEntries = accumEntries ? accumEntries.concat(entries) : entries;\n\n if (entries.length) {\n setTimeout(function() { // prevent stack overflow, however unlikely\n getFilesInDirectory(entry, dirReader, newEntries, promise);\n }, 0);\n }\n else {\n promise.success(newEntries);\n }\n },\n\n promise.failure\n );\n\n return promise;\n }\n\n function handleDataTransfer(dataTransfer, uploadDropZone) {\n var pendingFolderPromises = [],\n handleDataTransferPromise = new qq.Promise();\n\n options.callbacks.processingDroppedFiles();\n uploadDropZone.dropDisabled(true);\n\n if (dataTransfer.files.length > 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/dnd.min.js b/styles/bootstrap/fine-uploader/dnd.min.js new file mode 100644 index 000000000..1841817de --- /dev/null +++ b/styles/bootstrap/fine-uploader/dnd.min.js @@ -0,0 +1,3 @@ +// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com +!function(global){var qq=function(e){"use strict";return{hide:function(){return e.style.display="none",this},attach:function(n,t){return e.addEventListener?e.addEventListener(n,t,!1):e.attachEvent&&e.attachEvent("on"+n,t),function(){qq(e).detach(n,t)}},detach:function(n,t){return e.removeEventListener?e.removeEventListener(n,t,!1):e.attachEvent&&e.detachEvent("on"+n,t),this},contains:function(n){return!!n&&(e===n||(e.contains?e.contains(n):!!(8&n.compareDocumentPosition(e))))},insertBefore:function(n){return n.parentNode.insertBefore(e,n),this},remove:function(){return e.parentNode.removeChild(e),this},css:function(n){if(null==e.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=n.opacity&&"string"!=typeof e.style.opacity&&"undefined"!=typeof e.filters&&(n.filter="alpha(opacity="+Math.round(100*n.opacity)+")"),qq.extend(e.style,n),this},hasClass:function(n,t){var r=new RegExp("(^| )"+n+"( |$)");return r.test(e.className)||!(!t||!r.test(e.parentNode.className))},addClass:function(n){return qq(e).hasClass(n)||(e.className+=" "+n),this},removeClass:function(n){var t=new RegExp("(^| )"+n+"( |$)");return e.className=e.className.replace(t," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(n,t){var r,o=[];return t&&e.querySelector?e.querySelector("."+n):e.querySelectorAll?e.querySelectorAll("."+n):(r=e.getElementsByTagName("*"),qq.each(r,function(e,t){qq(t).hasClass(n)&&o.push(t)}),t?o[0]:o)},getFirstByClass:function(n){return qq(e).getByClass(n,!0)},children:function(){for(var n=[],t=e.firstChild;t;)1===t.nodeType&&n.push(t),t=t.nextSibling;return n},setText:function(n){return e.innerText=n,e.textContent=n,this},clearText:function(){return qq(e).setText("")},hasAttribute:function(n){var t;return e.hasAttribute?!!e.hasAttribute(n)&&null==/^false$/i.exec(e.getAttribute(n)):(t=e[n],void 0!==t&&null==/^false$/i.exec(t))}}};!function(){"use strict";qq.canvasToBlob=function(e,n,t){return qq.dataUriToBlob(e.toDataURL(n,t))},qq.dataUriToBlob=function(e){var n,t,r,o,i=function(e,n){var t=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,r=t&&new t;return r?(r.append(e),r.getBlob(n)):new Blob([e],{type:n})};return t=e.split(",")[0].indexOf("base64")>=0?atob(e.split(",")[1]):decodeURI(e.split(",")[1]),o=e.split(",")[0].split(":")[1].split(";")[0],n=new ArrayBuffer(t.length),r=new Uint8Array(n),qq.each(t,function(e,n){r[e]=n.charCodeAt(0)}),i(n,o)},qq.log=function(e,n){window.console&&(n&&"info"!==n?window.console[n]?window.console[n](e):window.console.log("<"+n+"> "+e):window.console.log(e))},qq.isObject=function(e){return e&&!e.nodeType&&"[object Object]"===Object.prototype.toString.call(e)},qq.isFunction=function(e){return"function"==typeof e},qq.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)||e&&window.ArrayBuffer&&e.buffer&&e.buffer.constructor===ArrayBuffer},qq.isItemList=function(e){return"[object DataTransferItemList]"===Object.prototype.toString.call(e)},qq.isNodeList=function(e){return"[object NodeList]"===Object.prototype.toString.call(e)||e.item&&e.namedItem},qq.isString=function(e){return"[object String]"===Object.prototype.toString.call(e)},qq.trimStr=function(e){return String.prototype.trim?e.trim():e.replace(/^\s+|\s+$/g,"")},qq.format=function(e){var n=Array.prototype.slice.call(arguments,1),t=e,r=t.indexOf("{}");return qq.each(n,function(e,n){var o=t.substring(0,r),i=t.substring(r+2);if(t=o+n+i,r=t.indexOf("{}",r+n.length),r<0)return!1}),t},qq.isFile=function(e){return window.File&&"[object File]"===Object.prototype.toString.call(e)},qq.isFileList=function(e){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(e)},qq.isFileOrInput=function(e){return qq.isFile(e)||qq.isInput(e)},qq.isInput=function(e,n){var t=function(e){var t=e.toLowerCase();return n?"file"!==t:"file"===t};return!!(window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(e)&&e.type&&t(e.type))||!!(e.tagName&&"input"===e.tagName.toLowerCase()&&e.type&&t(e.type))},qq.isBlob=function(e){if(window.Blob&&"[object Blob]"===Object.prototype.toString.call(e))return!0},qq.isXhrUploadSupported=function(){var e=document.createElement("input");return e.type="file",void 0!==e.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&"undefined"!=typeof qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(e){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(e){return e.items&&e.items.length>0&&e.items[0].webkitGetAsEntry},qq.isFileChunkingSupported=function(){return!qq.androidStock()&&qq.isXhrUploadSupported()&&(void 0!==File.prototype.slice||void 0!==File.prototype.webkitSlice||void 0!==File.prototype.mozSlice)},qq.sliceBlob=function(e,n,t){var r=e.slice||e.mozSlice||e.webkitSlice;return r.call(e,n,t)},qq.arrayBufferToHex=function(e){var n="",t=new Uint8Array(e);return qq.each(t,function(e,t){var r=t.toString(16);r.length<2&&(r="0"+r),n+=r}),n},qq.readBlobToHex=function(e,n,t){var r=qq.sliceBlob(e,n,n+t),o=new FileReader,i=new qq.Promise;return o.onload=function(){i.success(qq.arrayBufferToHex(o.result))},o.onerror=i.failure,o.readAsArrayBuffer(r),i},qq.extend=function(e,n,t){return qq.each(n,function(n,r){t&&qq.isObject(r)?(void 0===e[n]&&(e[n]={}),qq.extend(e[n],r,!0)):e[n]=r}),e},qq.override=function(e,n){var t={},r=n(t);return qq.each(r,function(n,r){void 0!==e[n]&&(t[n]=e[n]),e[n]=r}),e},qq.indexOf=function(e,n,t){if(e.indexOf)return e.indexOf(n,t);t=t||0;var r=e.length;for(t<0&&(t+=r);t=0},qq.safari=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Apple")!==-1},qq.chrome=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Google")!==-1},qq.opera=function(){return void 0!==navigator.vendor&&navigator.vendor.indexOf("Opera")!==-1},qq.firefox=function(){return!qq.edge()&&!qq.ie11()&&navigator.userAgent.indexOf("Mozilla")!==-1&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return navigator.userAgent.toLowerCase().indexOf("android")!==-1},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 6_")!==-1},qq.ios7=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 7_")!==-1},qq.ios8=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_")!==-1},qq.ios800=function(){return qq.ios()&&navigator.userAgent.indexOf(" OS 8_0 ")!==-1},qq.ios=function(){return navigator.userAgent.indexOf("iPad")!==-1||navigator.userAgent.indexOf("iPod")!==-1||navigator.userAgent.indexOf("iPhone")!==-1},qq.iosChrome=function(){return qq.ios()&&navigator.userAgent.indexOf("CriOS")!==-1},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&navigator.userAgent.indexOf("Safari")!==-1},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},qq.toElement=function(){var e=document.createElement("div");return function(n){e.innerHTML=n;var t=e.firstChild;return e.removeChild(t),t}}(),qq.each=function(e,n){var t,r;if(e)if(window.Storage&&e.constructor===window.Storage)for(t=0;t0)return e.substr(n,e.length-n)},qq.getFilename=function(e){return qq.isInput(e)?e.value.replace(/.*(\/|\\)/,""):qq.isFile(e)&&null!==e.fileName&&void 0!==e.fileName?e.fileName:e.name},qq.DisposeSupport=function(){var e=[];return{dispose:function(){var n;do n=e.shift(),n&&n();while(n)},attach:function(){var e=arguments;this.addDisposer(qq(e[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(n){e.push(n)}}}}(),function(){"use strict";"function"==typeof define&&define.amd?define(function(){return qq}):"undefined"!=typeof module&&module.exports?module.exports=qq:global.qq=qq}(),qq.version="5.12.0",qq.supportedFeatures=function(){"use strict";function e(){var e,n=!0;try{e=document.createElement("input"),e.type="file",qq(e).hide(),e.disabled&&(n=!1)}catch(e){n=!1}return n}function n(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function t(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function r(){if(window.XMLHttpRequest){var e=qq.createXhrInstance();return void 0!==e.withCredentials}return!1}function o(){return void 0!==window.XDomainRequest}function i(){return!!r()||o()}function a(){return void 0!==document.createElement("input").webkitdirectory}function u(){try{return!!window.localStorage&&qq.isFunction(window.localStorage.setItem)}catch(e){return!1}}function c(){var e=document.createElement("span");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&!qq.android()&&!qq.ios()}var s,l,q,f,d,p,g,v,h,m,y,b,w,x,E;return s=e(),f=s&&qq.isXhrUploadSupported(),l=f&&!qq.androidStock(),q=f&&c(),d=q&&n(),p=f&&qq.isFileChunkingSupported(),g=f&&p&&u(),v=f&&t(),h=s&&(void 0!==window.postMessage||f),y=r(),m=o(),b=i(),w=a(),x=f&&void 0!==window.FileReader,E=function(){return!!f&&(!qq.androidStock()&&!qq.iosChrome())}(),{ajaxUploading:f,blobUploading:l,canDetermineSize:f,chunking:p,deleteFileCors:b,deleteFileCorsXdr:m,deleteFileCorsXhr:y,dialogElement:!!window.HTMLDialogElement,fileDrop:q,folderDrop:d,folderSelection:w,imagePreviews:x,imageValidation:x,itemSizeValidation:f,pause:p,progressBar:E,resume:g,scaling:x&&l,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:s,uploadCors:h,uploadCustomHeaders:f,uploadNonMultipart:f,uploadViaPaste:v}}(),qq.isGenericPromise=function(e){"use strict";return!!(e&&e.then&&qq.isFunction(e.then))},qq.Promise=function(){"use strict";var e,n,t=[],r=[],o=[],i=0;qq.extend(this,{then:function(o,a){return 0===i?(o&&t.push(o),a&&r.push(a)):i===-1?a&&a.apply(null,n):o&&o.apply(null,e),this},done:function(t){return 0===i?o.push(t):t.apply(null,void 0===n?e:n),this},success:function(){return i=1,e=arguments,t.length&&qq.each(t,function(n,t){t.apply(null,e)}),o.length&&qq.each(o,function(n,t){t.apply(null,e)}),this},failure:function(){return i=-1,n=arguments,r.length&&qq.each(r,function(e,t){t.apply(null,n)}),o.length&&qq.each(o,function(e,t){t.apply(null,n)}),this}})},qq.DragAndDrop=function(e){"use strict";function n(e,n){var t=Array.prototype.slice.call(e);s.callbacks.dropLog("Grabbed "+e.length+" dropped files."),n.dropDisabled(!1),s.callbacks.processingDroppedFilesComplete(t,n.getElement())}function t(e){var n=new qq.Promise;return e.isFile?e.file(function(t){var r=e.name,o=e.fullPath,i=o.indexOf(r);o=o.substr(0,i),"/"===o.charAt(0)&&(o=o.substr(1)),t.qqPath=o,d.push(t),n.success()},function(t){s.callbacks.dropLog("Problem parsing '"+e.fullPath+"'. FileError code "+t.code+".","error"),n.failure()}):e.isDirectory&&r(e).then(function(e){var r=e.length;qq.each(e,function(e,o){t(o).done(function(){r-=1,0===r&&n.success()})}),e.length||n.success()},function(t){s.callbacks.dropLog("Problem parsing '"+e.fullPath+"'. FileError code "+t.code+".","error"),n.failure()}),n}function r(e,n,t,o){var i=o||new qq.Promise,a=n||e.createReader();return a.readEntries(function(n){var o=t?t.concat(n):n;n.length?setTimeout(function(){r(e,a,o,i)},0):i.success(o)},i.failure),i}function o(e,n){var r=[],o=new qq.Promise;return s.callbacks.processingDroppedFiles(),n.dropDisabled(!0),e.files.length>1&&!s.allowMultipleItems?(s.callbacks.processingDroppedFilesComplete([]),s.callbacks.dropError("tooManyFilesError",""),n.dropDisabled(!1),o.failure()):(d=[],qq.isFolderDropSupported(e)?qq.each(e.items,function(e,n){var i=n.webkitGetAsEntry();i&&(i.isFile?d.push(n.getAsFile()):r.push(t(i).done(function(){r.pop(),0===r.length&&o.success()})))}):d=e.files,0===r.length&&o.success()),o}function i(e){var t=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:l,element:e,onEnter:function(n){qq(e).addClass(s.classes.dropActive),n.stopPropagation()},onLeaveNotDescendants:function(n){qq(e).removeClass(s.classes.dropActive)},onDrop:function(e){o(e.dataTransfer,t).then(function(){n(d,t)},function(){s.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return p.addDisposer(function(){t.dispose()}),qq(e).hasAttribute(q)&&qq(e).hide(),f.push(t),t}function a(e){var n;return qq.each(e.dataTransfer.types,function(e,t){if("Files"===t)return n=!0,!1}),n}function u(e){return qq.firefox()?!e.relatedTarget:qq.safari()?e.x<0||e.y<0:0===e.x&&0===e.y}function c(){var e=s.dropZoneElements,n=function(){setTimeout(function(){qq.each(e,function(e,n){qq(n).hasAttribute(q)&&qq(n).hide(),qq(n).removeClass(s.classes.dropActive)})},10)};qq.each(e,function(n,t){var r=i(t);e.length&&qq.supportedFeatures.fileDrop&&p.attach(document,"dragenter",function(n){!r.dropDisabled()&&a(n)&&qq.each(e,function(e,n){n instanceof HTMLElement&&qq(n).hasAttribute(q)&&qq(n).css({display:"block"})})})}),p.attach(document,"dragleave",function(e){u(e)&&n()}),p.attach(qq(document).children()[0],"mouseenter",function(e){n()}),p.attach(document,"drop",function(e){e.preventDefault(),n()}),p.attach(document,l,n)}var s,l="qq-hidezones",q="qq-hide-dropzone",f=[],d=[],p=new qq.DisposeSupport;s={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(s,e,!0),c(),qq.extend(this,{setupExtraDropzone:function(e){s.dropZoneElements.push(e),i(e)},removeDropzone:function(e){var n,t=s.dropZoneElements;for(n in t)if(t[n]===e)return t.splice(n,1)},dispose:function(){p.dispose(),qq.each(f,function(e,n){n.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(e,n){},dropError:function(e,n){qq.log("Drag & drop error code '"+e+" with these specifics: '"+n+"'","error")},dropLog:function(e,n){qq.log(e,n)}}},qq.UploadDropZone=function(e){"use strict";function n(){return qq.safari()||qq.firefox()&&qq.windows()}function t(e){l||(n?q.attach(document,"dragover",function(e){e.preventDefault()}):q.attach(document,"dragover",function(e){e.dataTransfer&&(e.dataTransfer.dropEffect="none",e.preventDefault())}),l=!0)}function r(e){if(!qq.supportedFeatures.fileDrop)return!1;var n,t=e.dataTransfer,r=qq.safari();return n=!(!qq.ie()||!qq.supportedFeatures.fileDrop)||"none"!==t.effectAllowed,t&&n&&(t.files||!r&&t.types.contains&&t.types.contains("Files"))}function o(e){return void 0!==e&&(s=e),s}function i(){function e(){n=document.createEvent("Event"),n.initEvent(u.HIDE_ZONES_EVENT_NAME,!0,!0)}var n;if(window.CustomEvent)try{n=new CustomEvent(u.HIDE_ZONES_EVENT_NAME)}catch(n){e()}else e();document.dispatchEvent(n)}function a(){q.attach(c,"dragover",function(e){if(r(e)){var n=qq.ie()&&qq.supportedFeatures.fileDrop?null:e.dataTransfer.effectAllowed;"move"===n||"linkMove"===n?e.dataTransfer.dropEffect="move":e.dataTransfer.dropEffect="copy",e.stopPropagation(),e.preventDefault()}}),q.attach(c,"dragenter",function(e){if(!o()){if(!r(e))return;u.onEnter(e)}}),q.attach(c,"dragleave",function(e){if(r(e)){u.onLeave(e);var n=document.elementFromPoint(e.clientX,e.clientY);qq(this).contains(n)||u.onLeaveNotDescendants(e)}}),q.attach(c,"drop",function(e){if(!o()){if(!r(e))return;e.preventDefault(),e.stopPropagation(),u.onDrop(e),i()}})}var u,c,s,l,q=new qq.DisposeSupport;u={element:null,onEnter:function(e){},onLeave:function(e){},onLeaveNotDescendants:function(e){},onDrop:function(e){}},qq.extend(u,e),c=u.element,t(),a(),qq.extend(this,{dropDisabled:function(e){return o(e)},dispose:function(){q.dispose()},getElement:function(){return c}})}}(window); +//# sourceMappingURL=dnd.min.js.map \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/dnd.min.js.map b/styles/bootstrap/fine-uploader/dnd.min.js.map new file mode 100644 index 000000000..09622593c --- /dev/null +++ b/styles/bootstrap/fine-uploader/dnd.min.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["?","../client/js/util.js","../client/js/export.js","../client/js/version.js","../client/js/features.js","../client/js/promise.js","../client/js/dnd.js"],"names":["global","qq","element","hide","style","display","this","attach","type","fn","addEventListener","attachEvent","detach","removeEventListener","detachEvent","contains","descendant","compareDocumentPosition","insertBefore","elementB","parentNode","remove","removeChild","css","styles","Error","opacity","filter","Math","round","extend","hasClass","name","considerParent","re","RegExp","test","className","addClass","removeClass","replace","getByClass","first","candidates","result","querySelector","querySelectorAll","getElementsByTagName","each","idx","val","push","getFirstByClass","children","child","firstChild","nodeType","nextSibling","setText","text","innerText","textContent","clearText","hasAttribute","attrName","attrVal","exec","getAttribute","undefined","canvasToBlob","canvas","mime","quality","dataUriToBlob","toDataURL","dataUri","arrayBuffer","byteString","intArray","mimeString","createBlob","data","BlobBuilder","window","WebKitBlobBuilder","MozBlobBuilder","MSBlobBuilder","blobBuilder","append","getBlob","Blob","split","indexOf","atob","decodeURI","ArrayBuffer","length","Uint8Array","character","charCodeAt","log","message","level","console","isObject","variable","Object","prototype","toString","call","isFunction","isArray","value","buffer","constructor","isItemList","maybeItemList","isNodeList","maybeNodeList","item","namedItem","isString","maybeString","trimStr","string","String","trim","format","str","args","Array","slice","arguments","newStr","nextIdxToReplace","strBefore","substring","strAfter","isFile","maybeFile","File","isFileList","maybeFileList","FileList","isFileOrInput","maybeFileOrInput","isInput","maybeInput","notFile","evaluateType","normalizedType","toLowerCase","HTMLInputElement","tagName","isBlob","maybeBlob","isXhrUploadSupported","input","document","createElement","multiple","FormData","createXhrInstance","upload","XMLHttpRequest","ActiveXObject","error","isFolderDropSupported","dataTransfer","items","webkitGetAsEntry","isFileChunkingSupported","androidStock","webkitSlice","mozSlice","sliceBlob","fileOrBlob","start","end","slicer","arrayBufferToHex","bytesAsHex","bytes","byt","byteAsHexStr","readBlobToHex","blob","startOffset","initialBlob","fileReader","FileReader","promise","Promise","onload","success","onerror","failure","readAsArrayBuffer","second","extendNested","prop","override","target","sourceFn","super_","source","srcPropName","srcPropVal","arr","elt","from","len","hasOwnProperty","getUniqueId","c","r","random","v","ie","navigator","userAgent","ie7","ie8","ie10","ie11","edge","safari","vendor","chrome","opera","firefox","windows","platform","android","ios6","ios","ios7","ios8","ios800","iosChrome","iosSafari","iosSafariWebView","preventDefault","e","returnValue","toElement","div","html","innerHTML","iterableItem","callback","keyOrIndex","retVal","Storage","key","getItem","charAt","bind","oldFunc","context","newArgs","concat","apply","obj2url","obj","temp","prefixDone","uristrings","prefix","add","nextObj","i","nextTemp","encodeURIComponent","join","obj2FormData","formData","arrayKeyName","obj2Inputs","form","setAttribute","appendChild","parseJson","json","JSON","parse","eval","getExtension","filename","extIdx","lastIndexOf","substr","getFilename","blobOrFileInput","fileName","DisposeSupport","disposers","dispose","disposer","shift","addDisposer","disposeFunction","define","amd","module","exports","version","supportedFeatures","testSupportsFileInputElement","tempInput","supported","disabled","ex","isChrome21OrHigher","match","isChrome14OrHigher","isCrossOriginXhrSupported","xhr","withCredentials","isXdrSupported","XDomainRequest","isCrossOriginAjaxSupported","isFolderSelectionSupported","webkitdirectory","isLocalStorageSupported","localStorage","setItem","isDragAndDropSupported","span","supportsUploading","supportsUploadingBlobs","supportsFileDrop","supportsAjaxFileUploading","supportsFolderDrop","supportsChunking","supportsResume","supportsUploadViaPaste","supportsUploadCors","supportsDeleteFileXdr","supportsDeleteFileCorsXhr","supportsDeleteFileCors","supportsFolderSelection","supportsImagePreviews","supportsUploadProgress","postMessage","ajaxUploading","blobUploading","canDetermineSize","chunking","deleteFileCors","deleteFileCorsXdr","deleteFileCorsXhr","dialogElement","HTMLDialogElement","fileDrop","folderDrop","folderSelection","imagePreviews","imageValidation","itemSizeValidation","pause","progressBar","resume","scaling","tiffPreviews","unlimitedScaledImageSize","uploading","uploadCors","uploadCustomHeaders","uploadNonMultipart","uploadViaPaste","isGenericPromise","maybePromise","then","successArgs","failureArgs","successCallbacks","failureCallbacks","doneCallbacks","state","onSuccess","onFailure","done","DragAndDrop","o","uploadDroppedFiles","files","uploadDropZone","filesAsArray","options","callbacks","dropLog","dropDisabled","processingDroppedFilesComplete","getElement","traverseFileTree","entry","parseEntryPromise","file","fullPath","indexOfNameInFullPath","qqPath","droppedFiles","fileError","code","isDirectory","getFilesInDirectory","entries","entriesLeft","reader","accumEntries","existingPromise","dirReader","createReader","readEntries","newEntries","setTimeout","handleDataTransfer","pendingFolderPromises","handleDataTransferPromise","processingDroppedFiles","allowMultipleItems","dropError","getAsFile","pop","setupDropzone","dropArea","dropZone","UploadDropZone","HIDE_ZONES_EVENT_NAME","onEnter","classes","dropActive","stopPropagation","onLeaveNotDescendants","onDrop","disposeSupport","HIDE_BEFORE_ENTER_ATTR","uploadDropZones","isFileDrag","dragEvent","fileDrag","types","leavingDocumentOut","relatedTarget","x","y","setupDragDrop","dropZones","dropZoneElements","maybeHideDropZones","HTMLElement","setupExtraDropzone","removeDropzone","dzs","splice","targetEl","errorSpecifics","dragoverShouldBeCanceled","disableDropOutside","dropOutsideDisabled","dropEffect","isValidFileDrag","effectTest","dt","isSafari","effectAllowed","isOrSetDropDisabled","isDisabled","preventDrop","triggerHidezonesEvent","triggerUsingOldApi","hideZonesEvent","createEvent","initEvent","CustomEvent","err","dispatchEvent","attachEvents","effect","onLeave","elementFromPoint","clientX","clientY"],"mappings":"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","file":"dnd.min.js","sourcesContent":[null,"/*globals window, navigator, document, FormData, File, HTMLInputElement, XMLHttpRequest, Blob, Storage, ActiveXObject */\n/* jshint -W079 */\nvar qq = function(element) {\n \"use strict\";\n\n return {\n hide: function() {\n element.style.display = \"none\";\n return this;\n },\n\n /** Returns the function which detaches attached event */\n attach: function(type, fn) {\n if (element.addEventListener) {\n element.addEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.attachEvent(\"on\" + type, fn);\n }\n return function() {\n qq(element).detach(type, fn);\n };\n },\n\n detach: function(type, fn) {\n if (element.removeEventListener) {\n element.removeEventListener(type, fn, false);\n } else if (element.attachEvent) {\n element.detachEvent(\"on\" + type, fn);\n }\n return this;\n },\n\n contains: function(descendant) {\n // The [W3C spec](http://www.w3.org/TR/domcore/#dom-node-contains)\n // says a `null` (or ostensibly `undefined`) parameter\n // passed into `Node.contains` should result in a false return value.\n // IE7 throws an exception if the parameter is `undefined` though.\n if (!descendant) {\n return false;\n }\n\n // compareposition returns false in this case\n if (element === descendant) {\n return true;\n }\n\n if (element.contains) {\n return element.contains(descendant);\n } else {\n /*jslint bitwise: true*/\n return !!(descendant.compareDocumentPosition(element) & 8);\n }\n },\n\n /**\n * Insert this element before elementB.\n */\n insertBefore: function(elementB) {\n elementB.parentNode.insertBefore(element, elementB);\n return this;\n },\n\n remove: function() {\n element.parentNode.removeChild(element);\n return this;\n },\n\n /**\n * Sets styles for an element.\n * Fixes opacity in IE6-8.\n */\n css: function(styles) {\n /*jshint eqnull: true*/\n if (element.style == null) {\n throw new qq.Error(\"Can't apply style to node as it is not on the HTMLElement prototype chain!\");\n }\n\n /*jshint -W116*/\n if (styles.opacity != null) {\n if (typeof element.style.opacity !== \"string\" && typeof (element.filters) !== \"undefined\") {\n styles.filter = \"alpha(opacity=\" + Math.round(100 * styles.opacity) + \")\";\n }\n }\n qq.extend(element.style, styles);\n\n return this;\n },\n\n hasClass: function(name, considerParent) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className));\n },\n\n addClass: function(name) {\n if (!qq(element).hasClass(name)) {\n element.className += \" \" + name;\n }\n return this;\n },\n\n removeClass: function(name) {\n var re = new RegExp(\"(^| )\" + name + \"( |$)\");\n element.className = element.className.replace(re, \" \").replace(/^\\s+|\\s+$/g, \"\");\n return this;\n },\n\n getByClass: function(className, first) {\n var candidates,\n result = [];\n\n if (first && element.querySelector) {\n return element.querySelector(\".\" + className);\n }\n else if (element.querySelectorAll) {\n return element.querySelectorAll(\".\" + className);\n }\n\n candidates = element.getElementsByTagName(\"*\");\n\n qq.each(candidates, function(idx, val) {\n if (qq(val).hasClass(className)) {\n result.push(val);\n }\n });\n return first ? result[0] : result;\n },\n\n getFirstByClass: function(className) {\n return qq(element).getByClass(className, true);\n },\n\n children: function() {\n var children = [],\n child = element.firstChild;\n\n while (child) {\n if (child.nodeType === 1) {\n children.push(child);\n }\n child = child.nextSibling;\n }\n\n return children;\n },\n\n setText: function(text) {\n element.innerText = text;\n element.textContent = text;\n return this;\n },\n\n clearText: function() {\n return qq(element).setText(\"\");\n },\n\n // Returns true if the attribute exists on the element\n // AND the value of the attribute is NOT \"false\" (case-insensitive)\n hasAttribute: function(attrName) {\n var attrVal;\n\n if (element.hasAttribute) {\n\n if (!element.hasAttribute(attrName)) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(element.getAttribute(attrName)) == null;\n }\n else {\n attrVal = element[attrName];\n\n if (attrVal === undefined) {\n return false;\n }\n\n /*jshint -W116*/\n return (/^false$/i).exec(attrVal) == null;\n }\n }\n };\n};\n\n(function() {\n \"use strict\";\n\n qq.canvasToBlob = function(canvas, mime, quality) {\n return qq.dataUriToBlob(canvas.toDataURL(mime, quality));\n };\n\n qq.dataUriToBlob = function(dataUri) {\n var arrayBuffer, byteString,\n createBlob = function(data, mime) {\n var BlobBuilder = window.BlobBuilder ||\n window.WebKitBlobBuilder ||\n window.MozBlobBuilder ||\n window.MSBlobBuilder,\n blobBuilder = BlobBuilder && new BlobBuilder();\n\n if (blobBuilder) {\n blobBuilder.append(data);\n return blobBuilder.getBlob(mime);\n }\n else {\n return new Blob([data], {type: mime});\n }\n },\n intArray, mimeString;\n\n // convert base64 to raw binary data held in a string\n if (dataUri.split(\",\")[0].indexOf(\"base64\") >= 0) {\n byteString = atob(dataUri.split(\",\")[1]);\n }\n else {\n byteString = decodeURI(dataUri.split(\",\")[1]);\n }\n\n // extract the MIME\n mimeString = dataUri.split(\",\")[0]\n .split(\":\")[1]\n .split(\";\")[0];\n\n // write the bytes of the binary string to an ArrayBuffer\n arrayBuffer = new ArrayBuffer(byteString.length);\n intArray = new Uint8Array(arrayBuffer);\n qq.each(byteString, function(idx, character) {\n intArray[idx] = character.charCodeAt(0);\n });\n\n return createBlob(arrayBuffer, mimeString);\n };\n\n qq.log = function(message, level) {\n if (window.console) {\n if (!level || level === \"info\") {\n window.console.log(message);\n }\n else\n {\n if (window.console[level]) {\n window.console[level](message);\n }\n else {\n window.console.log(\"<\" + level + \"> \" + message);\n }\n }\n }\n };\n\n qq.isObject = function(variable) {\n return variable && !variable.nodeType && Object.prototype.toString.call(variable) === \"[object Object]\";\n };\n\n qq.isFunction = function(variable) {\n return typeof (variable) === \"function\";\n };\n\n /**\n * Check the type of a value. Is it an \"array\"?\n *\n * @param value value to test.\n * @returns true if the value is an array or associated with an `ArrayBuffer`\n */\n qq.isArray = function(value) {\n return Object.prototype.toString.call(value) === \"[object Array]\" ||\n (value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer);\n };\n\n // Looks for an object on a `DataTransfer` object that is associated with drop events when utilizing the Filesystem API.\n qq.isItemList = function(maybeItemList) {\n return Object.prototype.toString.call(maybeItemList) === \"[object DataTransferItemList]\";\n };\n\n // Looks for an object on a `NodeList` or an `HTMLCollection`|`HTMLFormElement`|`HTMLSelectElement`\n // object that is associated with collections of Nodes.\n qq.isNodeList = function(maybeNodeList) {\n return Object.prototype.toString.call(maybeNodeList) === \"[object NodeList]\" ||\n // If `HTMLCollection` is the actual type of the object, we must determine this\n // by checking for expected properties/methods on the object\n (maybeNodeList.item && maybeNodeList.namedItem);\n };\n\n qq.isString = function(maybeString) {\n return Object.prototype.toString.call(maybeString) === \"[object String]\";\n };\n\n qq.trimStr = function(string) {\n if (String.prototype.trim) {\n return string.trim();\n }\n\n return string.replace(/^\\s+|\\s+$/g, \"\");\n };\n\n /**\n * @param str String to format.\n * @returns {string} A string, swapping argument values with the associated occurrence of {} in the passed string.\n */\n qq.format = function(str) {\n\n var args = Array.prototype.slice.call(arguments, 1),\n newStr = str,\n nextIdxToReplace = newStr.indexOf(\"{}\");\n\n qq.each(args, function(idx, val) {\n var strBefore = newStr.substring(0, nextIdxToReplace),\n strAfter = newStr.substring(nextIdxToReplace + 2);\n\n newStr = strBefore + val + strAfter;\n nextIdxToReplace = newStr.indexOf(\"{}\", nextIdxToReplace + val.length);\n\n // End the loop if we have run out of tokens (when the arguments exceed the # of tokens)\n if (nextIdxToReplace < 0) {\n return false;\n }\n });\n\n return newStr;\n };\n\n qq.isFile = function(maybeFile) {\n return window.File && Object.prototype.toString.call(maybeFile) === \"[object File]\";\n };\n\n qq.isFileList = function(maybeFileList) {\n return window.FileList && Object.prototype.toString.call(maybeFileList) === \"[object FileList]\";\n };\n\n qq.isFileOrInput = function(maybeFileOrInput) {\n return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput);\n };\n\n qq.isInput = function(maybeInput, notFile) {\n var evaluateType = function(type) {\n var normalizedType = type.toLowerCase();\n\n if (notFile) {\n return normalizedType !== \"file\";\n }\n\n return normalizedType === \"file\";\n };\n\n if (window.HTMLInputElement) {\n if (Object.prototype.toString.call(maybeInput) === \"[object HTMLInputElement]\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n if (maybeInput.tagName) {\n if (maybeInput.tagName.toLowerCase() === \"input\") {\n if (maybeInput.type && evaluateType(maybeInput.type)) {\n return true;\n }\n }\n }\n\n return false;\n };\n\n qq.isBlob = function(maybeBlob) {\n if (window.Blob && Object.prototype.toString.call(maybeBlob) === \"[object Blob]\") {\n return true;\n }\n };\n\n qq.isXhrUploadSupported = function() {\n var input = document.createElement(\"input\");\n input.type = \"file\";\n\n return (\n input.multiple !== undefined &&\n typeof File !== \"undefined\" &&\n typeof FormData !== \"undefined\" &&\n typeof (qq.createXhrInstance()).upload !== \"undefined\");\n };\n\n // Fall back to ActiveX is native XHR is disabled (possible in any version of IE).\n qq.createXhrInstance = function() {\n if (window.XMLHttpRequest) {\n return new XMLHttpRequest();\n }\n\n try {\n return new ActiveXObject(\"MSXML2.XMLHTTP.3.0\");\n }\n catch (error) {\n qq.log(\"Neither XHR or ActiveX are supported!\", \"error\");\n return null;\n }\n };\n\n qq.isFolderDropSupported = function(dataTransfer) {\n return dataTransfer.items &&\n dataTransfer.items.length > 0 &&\n dataTransfer.items[0].webkitGetAsEntry;\n };\n\n qq.isFileChunkingSupported = function() {\n return !qq.androidStock() && //Android's stock browser cannot upload Blobs correctly\n qq.isXhrUploadSupported() &&\n (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined);\n };\n\n qq.sliceBlob = function(fileOrBlob, start, end) {\n var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice;\n\n return slicer.call(fileOrBlob, start, end);\n };\n\n qq.arrayBufferToHex = function(buffer) {\n var bytesAsHex = \"\",\n bytes = new Uint8Array(buffer);\n\n qq.each(bytes, function(idx, byt) {\n var byteAsHexStr = byt.toString(16);\n\n if (byteAsHexStr.length < 2) {\n byteAsHexStr = \"0\" + byteAsHexStr;\n }\n\n bytesAsHex += byteAsHexStr;\n });\n\n return bytesAsHex;\n };\n\n qq.readBlobToHex = function(blob, startOffset, length) {\n var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length),\n fileReader = new FileReader(),\n promise = new qq.Promise();\n\n fileReader.onload = function() {\n promise.success(qq.arrayBufferToHex(fileReader.result));\n };\n\n fileReader.onerror = promise.failure;\n\n fileReader.readAsArrayBuffer(initialBlob);\n\n return promise;\n };\n\n qq.extend = function(first, second, extendNested) {\n qq.each(second, function(prop, val) {\n if (extendNested && qq.isObject(val)) {\n if (first[prop] === undefined) {\n first[prop] = {};\n }\n qq.extend(first[prop], val, true);\n }\n else {\n first[prop] = val;\n }\n });\n\n return first;\n };\n\n /**\n * Allow properties in one object to override properties in another,\n * keeping track of the original values from the target object.\n *\n * Note that the pre-overriden properties to be overriden by the source will be passed into the `sourceFn` when it is invoked.\n *\n * @param target Update properties in this object from some source\n * @param sourceFn A function that, when invoked, will return properties that will replace properties with the same name in the target.\n * @returns {object} The target object\n */\n qq.override = function(target, sourceFn) {\n var super_ = {},\n source = sourceFn(super_);\n\n qq.each(source, function(srcPropName, srcPropVal) {\n if (target[srcPropName] !== undefined) {\n super_[srcPropName] = target[srcPropName];\n }\n\n target[srcPropName] = srcPropVal;\n });\n\n return target;\n };\n\n /**\n * Searches for a given element (elt) in the array, returns -1 if it is not present.\n */\n qq.indexOf = function(arr, elt, from) {\n if (arr.indexOf) {\n return arr.indexOf(elt, from);\n }\n\n from = from || 0;\n var len = arr.length;\n\n if (from < 0) {\n from += len;\n }\n\n for (; from < len; from += 1) {\n if (arr.hasOwnProperty(from) && arr[from] === elt) {\n return from;\n }\n }\n return -1;\n };\n\n //this is a version 4 UUID\n qq.getUniqueId = function() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, function(c) {\n /*jslint eqeq: true, bitwise: true*/\n var r = Math.random() * 16 | 0, v = c == \"x\" ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n };\n\n //\n // Browsers and platforms detection\n qq.ie = function() {\n return navigator.userAgent.indexOf(\"MSIE\") !== -1 ||\n navigator.userAgent.indexOf(\"Trident\") !== -1;\n };\n\n qq.ie7 = function() {\n return navigator.userAgent.indexOf(\"MSIE 7\") !== -1;\n };\n\n qq.ie8 = function() {\n return navigator.userAgent.indexOf(\"MSIE 8\") !== -1;\n };\n\n qq.ie10 = function() {\n return navigator.userAgent.indexOf(\"MSIE 10\") !== -1;\n };\n\n qq.ie11 = function() {\n return qq.ie() && navigator.userAgent.indexOf(\"rv:11\") !== -1;\n };\n\n qq.edge = function() {\n return navigator.userAgent.indexOf(\"Edge\") >= 0;\n };\n\n qq.safari = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Apple\") !== -1;\n };\n\n qq.chrome = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Google\") !== -1;\n };\n\n qq.opera = function() {\n return navigator.vendor !== undefined && navigator.vendor.indexOf(\"Opera\") !== -1;\n };\n\n qq.firefox = function() {\n return (!qq.edge() && !qq.ie11() && navigator.userAgent.indexOf(\"Mozilla\") !== -1 && navigator.vendor !== undefined && navigator.vendor === \"\");\n };\n\n qq.windows = function() {\n return navigator.platform === \"Win32\";\n };\n\n qq.android = function() {\n return navigator.userAgent.toLowerCase().indexOf(\"android\") !== -1;\n };\n\n // We need to identify the Android stock browser via the UA string to work around various bugs in this browser,\n // such as the one that prevents a `Blob` from being uploaded.\n qq.androidStock = function() {\n return qq.android() && navigator.userAgent.toLowerCase().indexOf(\"chrome\") < 0;\n };\n\n qq.ios6 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 6_\") !== -1;\n };\n\n qq.ios7 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 7_\") !== -1;\n };\n\n qq.ios8 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_\") !== -1;\n };\n\n // iOS 8.0.0\n qq.ios800 = function() {\n return qq.ios() && navigator.userAgent.indexOf(\" OS 8_0 \") !== -1;\n };\n\n qq.ios = function() {\n /*jshint -W014 */\n return navigator.userAgent.indexOf(\"iPad\") !== -1\n || navigator.userAgent.indexOf(\"iPod\") !== -1\n || navigator.userAgent.indexOf(\"iPhone\") !== -1;\n };\n\n qq.iosChrome = function() {\n return qq.ios() && navigator.userAgent.indexOf(\"CriOS\") !== -1;\n };\n\n qq.iosSafari = function() {\n return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf(\"Safari\") !== -1;\n };\n\n qq.iosSafariWebView = function() {\n return qq.ios() && !qq.iosChrome() && !qq.iosSafari();\n };\n\n //\n // Events\n\n qq.preventDefault = function(e) {\n if (e.preventDefault) {\n e.preventDefault();\n } else {\n e.returnValue = false;\n }\n };\n\n /**\n * Creates and returns element from html string\n * Uses innerHTML to create an element\n */\n qq.toElement = (function() {\n var div = document.createElement(\"div\");\n return function(html) {\n div.innerHTML = html;\n var element = div.firstChild;\n div.removeChild(element);\n return element;\n };\n }());\n\n //key and value are passed to callback for each entry in the iterable item\n qq.each = function(iterableItem, callback) {\n var keyOrIndex, retVal;\n\n if (iterableItem) {\n // Iterate through [`Storage`](http://www.w3.org/TR/webstorage/#the-storage-interface) items\n if (window.Storage && iterableItem.constructor === window.Storage) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex)));\n if (retVal === false) {\n break;\n }\n }\n }\n // `DataTransferItemList` & `NodeList` objects are array-like and should be treated as arrays\n // when iterating over items inside the object.\n else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n else if (qq.isString(iterableItem)) {\n for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) {\n retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex));\n if (retVal === false) {\n break;\n }\n }\n }\n else {\n for (keyOrIndex in iterableItem) {\n if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) {\n retVal = callback(keyOrIndex, iterableItem[keyOrIndex]);\n if (retVal === false) {\n break;\n }\n }\n }\n }\n }\n };\n\n //include any args that should be passed to the new function after the context arg\n qq.bind = function(oldFunc, context) {\n if (qq.isFunction(oldFunc)) {\n var args = Array.prototype.slice.call(arguments, 2);\n\n return function() {\n var newArgs = qq.extend([], args);\n if (arguments.length) {\n newArgs = newArgs.concat(Array.prototype.slice.call(arguments));\n }\n return oldFunc.apply(context, newArgs);\n };\n }\n\n throw new Error(\"first parameter must be a function!\");\n };\n\n /**\n * obj2url() takes a json-object as argument and generates\n * a querystring. pretty much like jQuery.param()\n *\n * how to use:\n *\n * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`\n *\n * will result in:\n *\n * `http://any.url/upload?otherParam=value&a=b&c=d`\n *\n * @param Object JSON-Object\n * @param String current querystring-part\n * @return String encoded querystring\n */\n qq.obj2url = function(obj, temp, prefixDone) {\n /*jshint laxbreak: true*/\n var uristrings = [],\n prefix = \"&\",\n add = function(nextObj, i) {\n var nextTemp = temp\n ? (/\\[\\]$/.test(temp)) // prevent double-encoding\n ? temp\n : temp + \"[\" + i + \"]\"\n : i;\n if ((nextTemp !== \"undefined\") && (i !== \"undefined\")) {\n uristrings.push(\n (typeof nextObj === \"object\")\n ? qq.obj2url(nextObj, nextTemp, true)\n : (Object.prototype.toString.call(nextObj) === \"[object Function]\")\n ? encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj())\n : encodeURIComponent(nextTemp) + \"=\" + encodeURIComponent(nextObj)\n );\n }\n };\n\n if (!prefixDone && temp) {\n prefix = (/\\?/.test(temp)) ? (/\\?$/.test(temp)) ? \"\" : \"&\" : \"?\";\n uristrings.push(temp);\n uristrings.push(qq.obj2url(obj));\n } else if ((Object.prototype.toString.call(obj) === \"[object Array]\") && (typeof obj !== \"undefined\")) {\n qq.each(obj, function(idx, val) {\n add(val, idx);\n });\n } else if ((typeof obj !== \"undefined\") && (obj !== null) && (typeof obj === \"object\")) {\n qq.each(obj, function(prop, val) {\n add(val, prop);\n });\n } else {\n uristrings.push(encodeURIComponent(temp) + \"=\" + encodeURIComponent(obj));\n }\n\n if (temp) {\n return uristrings.join(prefix);\n } else {\n return uristrings.join(prefix)\n .replace(/^&/, \"\")\n .replace(/%20/g, \"+\");\n }\n };\n\n qq.obj2FormData = function(obj, formData, arrayKeyName) {\n if (!formData) {\n formData = new FormData();\n }\n\n qq.each(obj, function(key, val) {\n key = arrayKeyName ? arrayKeyName + \"[\" + key + \"]\" : key;\n\n if (qq.isObject(val)) {\n qq.obj2FormData(val, formData, key);\n }\n else if (qq.isFunction(val)) {\n formData.append(key, val());\n }\n else {\n formData.append(key, val);\n }\n });\n\n return formData;\n };\n\n qq.obj2Inputs = function(obj, form) {\n var input;\n\n if (!form) {\n form = document.createElement(\"form\");\n }\n\n qq.obj2FormData(obj, {\n append: function(key, val) {\n input = document.createElement(\"input\");\n input.setAttribute(\"name\", key);\n input.setAttribute(\"value\", val);\n form.appendChild(input);\n }\n });\n\n return form;\n };\n\n /**\n * Not recommended for use outside of Fine Uploader since this falls back to an unchecked eval if JSON.parse is not\n * implemented. For a more secure JSON.parse polyfill, use Douglas Crockford's json2.js.\n */\n qq.parseJson = function(json) {\n /*jshint evil: true*/\n if (window.JSON && qq.isFunction(JSON.parse)) {\n return JSON.parse(json);\n } else {\n return eval(\"(\" + json + \")\");\n }\n };\n\n /**\n * Retrieve the extension of a file, if it exists.\n *\n * @param filename\n * @returns {string || undefined}\n */\n qq.getExtension = function(filename) {\n var extIdx = filename.lastIndexOf(\".\") + 1;\n\n if (extIdx > 0) {\n return filename.substr(extIdx, filename.length - extIdx);\n }\n };\n\n qq.getFilename = function(blobOrFileInput) {\n /*jslint regexp: true*/\n\n if (qq.isInput(blobOrFileInput)) {\n // get input value and remove path to normalize\n return blobOrFileInput.value.replace(/.*(\\/|\\\\)/, \"\");\n }\n else if (qq.isFile(blobOrFileInput)) {\n if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) {\n return blobOrFileInput.fileName;\n }\n }\n\n return blobOrFileInput.name;\n };\n\n /**\n * A generic module which supports object disposing in dispose() method.\n * */\n qq.DisposeSupport = function() {\n var disposers = [];\n\n return {\n /** Run all registered disposers */\n dispose: function() {\n var disposer;\n do {\n disposer = disposers.shift();\n if (disposer) {\n disposer();\n }\n }\n while (disposer);\n },\n\n /** Attach event handler and register de-attacher as a disposer */\n attach: function() {\n var args = arguments;\n /*jslint undef:true*/\n this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1)));\n },\n\n /** Add disposer to the collection */\n addDisposer: function(disposeFunction) {\n disposers.push(disposeFunction);\n }\n };\n };\n}());\n","/* globals define, module, global, qq */\n(function() {\n \"use strict\";\n if (typeof define === \"function\" && define.amd) {\n define(function() {\n return qq;\n });\n }\n else if (typeof module !== \"undefined\" && module.exports) {\n module.exports = qq;\n }\n else {\n global.qq = qq;\n }\n}());\n","/*global qq */\nqq.version = \"5.12.0\";\n","/* globals qq */\nqq.supportedFeatures = (function() {\n \"use strict\";\n\n var supportsUploading,\n supportsUploadingBlobs,\n supportsFileDrop,\n supportsAjaxFileUploading,\n supportsFolderDrop,\n supportsChunking,\n supportsResume,\n supportsUploadViaPaste,\n supportsUploadCors,\n supportsDeleteFileXdr,\n supportsDeleteFileCorsXhr,\n supportsDeleteFileCors,\n supportsFolderSelection,\n supportsImagePreviews,\n supportsUploadProgress;\n\n function testSupportsFileInputElement() {\n var supported = true,\n tempInput;\n\n try {\n tempInput = document.createElement(\"input\");\n tempInput.type = \"file\";\n qq(tempInput).hide();\n\n if (tempInput.disabled) {\n supported = false;\n }\n }\n catch (ex) {\n supported = false;\n }\n\n return supported;\n }\n\n //only way to test for Filesystem API support since webkit does not expose the DataTransfer interface\n function isChrome21OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[2][1-9]|Chrome\\/[3-9][0-9]/) !== undefined;\n }\n\n //only way to test for complete Clipboard API support at this time\n function isChrome14OrHigher() {\n return (qq.chrome() || qq.opera()) &&\n navigator.userAgent.match(/Chrome\\/[1][4-9]|Chrome\\/[2-9][0-9]/) !== undefined;\n }\n\n //Ensure we can send cross-origin `XMLHttpRequest`s\n function isCrossOriginXhrSupported() {\n if (window.XMLHttpRequest) {\n var xhr = qq.createXhrInstance();\n\n //Commonly accepted test for XHR CORS support.\n return xhr.withCredentials !== undefined;\n }\n\n return false;\n }\n\n //Test for (terrible) cross-origin ajax transport fallback for IE9 and IE8\n function isXdrSupported() {\n return window.XDomainRequest !== undefined;\n }\n\n // CORS Ajax requests are supported if it is either possible to send credentialed `XMLHttpRequest`s,\n // or if `XDomainRequest` is an available alternative.\n function isCrossOriginAjaxSupported() {\n if (isCrossOriginXhrSupported()) {\n return true;\n }\n\n return isXdrSupported();\n }\n\n function isFolderSelectionSupported() {\n // We know that folder selection is only supported in Chrome via this proprietary attribute for now\n return document.createElement(\"input\").webkitdirectory !== undefined;\n }\n\n function isLocalStorageSupported() {\n try {\n return !!window.localStorage &&\n // unpatched versions of IE10/11 have buggy impls of localStorage where setItem is a string\n qq.isFunction(window.localStorage.setItem);\n }\n catch (error) {\n // probably caught a security exception, so no localStorage for you\n return false;\n }\n }\n\n function isDragAndDropSupported() {\n var span = document.createElement(\"span\");\n\n return (\"draggable\" in span || (\"ondragstart\" in span && \"ondrop\" in span)) &&\n !qq.android() && !qq.ios();\n }\n\n supportsUploading = testSupportsFileInputElement();\n\n supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported();\n\n supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock();\n\n supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported();\n\n supportsFolderDrop = supportsFileDrop && isChrome21OrHigher();\n\n supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported();\n\n supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported();\n\n supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher();\n\n supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading);\n\n supportsDeleteFileCorsXhr = isCrossOriginXhrSupported();\n\n supportsDeleteFileXdr = isXdrSupported();\n\n supportsDeleteFileCors = isCrossOriginAjaxSupported();\n\n supportsFolderSelection = isFolderSelectionSupported();\n\n supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined;\n\n supportsUploadProgress = (function() {\n if (supportsAjaxFileUploading) {\n return !qq.androidStock() && !qq.iosChrome();\n }\n return false;\n }());\n\n return {\n ajaxUploading: supportsAjaxFileUploading,\n blobUploading: supportsUploadingBlobs,\n canDetermineSize: supportsAjaxFileUploading,\n chunking: supportsChunking,\n deleteFileCors: supportsDeleteFileCors,\n deleteFileCorsXdr: supportsDeleteFileXdr, //NOTE: will also return true in IE10, where XDR is also supported\n deleteFileCorsXhr: supportsDeleteFileCorsXhr,\n dialogElement: !!window.HTMLDialogElement,\n fileDrop: supportsFileDrop,\n folderDrop: supportsFolderDrop,\n folderSelection: supportsFolderSelection,\n imagePreviews: supportsImagePreviews,\n imageValidation: supportsImagePreviews,\n itemSizeValidation: supportsAjaxFileUploading,\n pause: supportsChunking,\n progressBar: supportsUploadProgress,\n resume: supportsResume,\n scaling: supportsImagePreviews && supportsUploadingBlobs,\n tiffPreviews: qq.safari(), // Not the best solution, but simple and probably accurate enough (for now)\n unlimitedScaledImageSize: !qq.ios(), // false simply indicates that there is some known limit\n uploading: supportsUploading,\n uploadCors: supportsUploadCors,\n uploadCustomHeaders: supportsAjaxFileUploading,\n uploadNonMultipart: supportsAjaxFileUploading,\n uploadViaPaste: supportsUploadViaPaste\n };\n\n}());\n","/*globals qq*/\n\n// Is the passed object a promise instance?\nqq.isGenericPromise = function(maybePromise) {\n \"use strict\";\n return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then));\n};\n\nqq.Promise = function() {\n \"use strict\";\n\n var successArgs, failureArgs,\n successCallbacks = [],\n failureCallbacks = [],\n doneCallbacks = [],\n state = 0;\n\n qq.extend(this, {\n then: function(onSuccess, onFailure) {\n if (state === 0) {\n if (onSuccess) {\n successCallbacks.push(onSuccess);\n }\n if (onFailure) {\n failureCallbacks.push(onFailure);\n }\n }\n else if (state === -1) {\n onFailure && onFailure.apply(null, failureArgs);\n }\n else if (onSuccess) {\n onSuccess.apply(null, successArgs);\n }\n\n return this;\n },\n\n done: function(callback) {\n if (state === 0) {\n doneCallbacks.push(callback);\n }\n else {\n callback.apply(null, failureArgs === undefined ? successArgs : failureArgs);\n }\n\n return this;\n },\n\n success: function() {\n state = 1;\n successArgs = arguments;\n\n if (successCallbacks.length) {\n qq.each(successCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, successArgs);\n });\n }\n\n return this;\n },\n\n failure: function() {\n state = -1;\n failureArgs = arguments;\n\n if (failureCallbacks.length) {\n qq.each(failureCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n if (doneCallbacks.length) {\n qq.each(doneCallbacks, function(idx, callback) {\n callback.apply(null, failureArgs);\n });\n }\n\n return this;\n }\n });\n};\n","/*globals qq, document, CustomEvent*/\nqq.DragAndDrop = function(o) {\n \"use strict\";\n\n var options,\n HIDE_ZONES_EVENT_NAME = \"qq-hidezones\",\n HIDE_BEFORE_ENTER_ATTR = \"qq-hide-dropzone\",\n uploadDropZones = [],\n droppedFiles = [],\n disposeSupport = new qq.DisposeSupport();\n\n options = {\n dropZoneElements: [],\n allowMultipleItems: true,\n classes: {\n dropActive: null\n },\n callbacks: new qq.DragAndDrop.callbacks()\n };\n\n qq.extend(options, o, true);\n\n function uploadDroppedFiles(files, uploadDropZone) {\n // We need to convert the `FileList` to an actual `Array` to avoid iteration issues\n var filesAsArray = Array.prototype.slice.call(files);\n\n options.callbacks.dropLog(\"Grabbed \" + files.length + \" dropped files.\");\n uploadDropZone.dropDisabled(false);\n options.callbacks.processingDroppedFilesComplete(filesAsArray, uploadDropZone.getElement());\n }\n\n function traverseFileTree(entry) {\n var parseEntryPromise = new qq.Promise();\n\n if (entry.isFile) {\n entry.file(function(file) {\n var name = entry.name,\n fullPath = entry.fullPath,\n indexOfNameInFullPath = fullPath.indexOf(name);\n\n // remove file name from full path string\n fullPath = fullPath.substr(0, indexOfNameInFullPath);\n\n // remove leading slash in full path string\n if (fullPath.charAt(0) === \"/\") {\n fullPath = fullPath.substr(1);\n }\n\n file.qqPath = fullPath;\n droppedFiles.push(file);\n parseEntryPromise.success();\n },\n function(fileError) {\n options.callbacks.dropLog(\"Problem parsing '\" + entry.fullPath + \"'. FileError code \" + fileError.code + \".\", \"error\");\n parseEntryPromise.failure();\n });\n }\n else if (entry.isDirectory) {\n getFilesInDirectory(entry).then(\n function allEntriesRead(entries) {\n var entriesLeft = entries.length;\n\n qq.each(entries, function(idx, entry) {\n traverseFileTree(entry).done(function() {\n entriesLeft -= 1;\n\n if (entriesLeft === 0) {\n parseEntryPromise.success();\n }\n });\n });\n\n if (!entries.length) {\n parseEntryPromise.success();\n }\n },\n\n function readFailure(fileError) {\n options.callbacks.dropLog(\"Problem parsing '\" + entry.fullPath + \"'. FileError code \" + fileError.code + \".\", \"error\");\n parseEntryPromise.failure();\n }\n );\n }\n\n return parseEntryPromise;\n }\n\n // Promissory. Guaranteed to read all files in the root of the passed directory.\n function getFilesInDirectory(entry, reader, accumEntries, existingPromise) {\n var promise = existingPromise || new qq.Promise(),\n dirReader = reader || entry.createReader();\n\n dirReader.readEntries(\n function readSuccess(entries) {\n var newEntries = accumEntries ? accumEntries.concat(entries) : entries;\n\n if (entries.length) {\n setTimeout(function() { // prevent stack overflow, however unlikely\n getFilesInDirectory(entry, dirReader, newEntries, promise);\n }, 0);\n }\n else {\n promise.success(newEntries);\n }\n },\n\n promise.failure\n );\n\n return promise;\n }\n\n function handleDataTransfer(dataTransfer, uploadDropZone) {\n var pendingFolderPromises = [],\n handleDataTransferPromise = new qq.Promise();\n\n options.callbacks.processingDroppedFiles();\n uploadDropZone.dropDisabled(true);\n\n if (dataTransfer.files.length > 1 && !options.allowMultipleItems) {\n options.callbacks.processingDroppedFilesComplete([]);\n options.callbacks.dropError(\"tooManyFilesError\", \"\");\n uploadDropZone.dropDisabled(false);\n handleDataTransferPromise.failure();\n }\n else {\n droppedFiles = [];\n\n if (qq.isFolderDropSupported(dataTransfer)) {\n qq.each(dataTransfer.items, function(idx, item) {\n var entry = item.webkitGetAsEntry();\n\n if (entry) {\n //due to a bug in Chrome's File System API impl - #149735\n if (entry.isFile) {\n droppedFiles.push(item.getAsFile());\n }\n\n else {\n pendingFolderPromises.push(traverseFileTree(entry).done(function() {\n pendingFolderPromises.pop();\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }));\n }\n }\n });\n }\n else {\n droppedFiles = dataTransfer.files;\n }\n\n if (pendingFolderPromises.length === 0) {\n handleDataTransferPromise.success();\n }\n }\n\n return handleDataTransferPromise;\n }\n\n function setupDropzone(dropArea) {\n var dropZone = new qq.UploadDropZone({\n HIDE_ZONES_EVENT_NAME: HIDE_ZONES_EVENT_NAME,\n element: dropArea,\n onEnter: function(e) {\n qq(dropArea).addClass(options.classes.dropActive);\n e.stopPropagation();\n },\n onLeaveNotDescendants: function(e) {\n qq(dropArea).removeClass(options.classes.dropActive);\n },\n onDrop: function(e) {\n handleDataTransfer(e.dataTransfer, dropZone).then(\n function() {\n uploadDroppedFiles(droppedFiles, dropZone);\n },\n function() {\n options.callbacks.dropLog(\"Drop event DataTransfer parsing failed. No files will be uploaded.\", \"error\");\n }\n );\n }\n });\n\n disposeSupport.addDisposer(function() {\n dropZone.dispose();\n });\n\n qq(dropArea).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropArea).hide();\n\n uploadDropZones.push(dropZone);\n\n return dropZone;\n }\n\n function isFileDrag(dragEvent) {\n var fileDrag;\n\n qq.each(dragEvent.dataTransfer.types, function(key, val) {\n if (val === \"Files\") {\n fileDrag = true;\n return false;\n }\n });\n\n return fileDrag;\n }\n\n // Attempt to determine when the file has left the document. It is not always possible to detect this\n // in all cases, but it is generally possible in all browsers, with a few exceptions.\n //\n // Exceptions:\n // * IE10+ & Safari: We can't detect a file leaving the document if the Explorer window housing the file\n // overlays the browser window.\n // * IE10+: If the file is dragged out of the window too quickly, IE does not set the expected values of the\n // event's X & Y properties.\n function leavingDocumentOut(e) {\n if (qq.firefox()) {\n return !e.relatedTarget;\n }\n\n if (qq.safari()) {\n return e.x < 0 || e.y < 0;\n }\n\n return e.x === 0 && e.y === 0;\n }\n\n function setupDragDrop() {\n var dropZones = options.dropZoneElements,\n\n maybeHideDropZones = function() {\n setTimeout(function() {\n qq.each(dropZones, function(idx, dropZone) {\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR) && qq(dropZone).hide();\n qq(dropZone).removeClass(options.classes.dropActive);\n });\n }, 10);\n };\n\n qq.each(dropZones, function(idx, dropZone) {\n var uploadDropZone = setupDropzone(dropZone);\n\n // IE <= 9 does not support the File API used for drag+drop uploads\n if (dropZones.length && qq.supportedFeatures.fileDrop) {\n disposeSupport.attach(document, \"dragenter\", function(e) {\n if (!uploadDropZone.dropDisabled() && isFileDrag(e)) {\n qq.each(dropZones, function(idx, dropZone) {\n // We can't apply styles to non-HTMLElements, since they lack the `style` property.\n // Also, if the drop zone isn't initially hidden, let's not mess with `style.display`.\n if (dropZone instanceof HTMLElement &&\n qq(dropZone).hasAttribute(HIDE_BEFORE_ENTER_ATTR)) {\n\n qq(dropZone).css({display: \"block\"});\n }\n });\n }\n });\n }\n });\n\n disposeSupport.attach(document, \"dragleave\", function(e) {\n if (leavingDocumentOut(e)) {\n maybeHideDropZones();\n }\n });\n\n // Just in case we were not able to detect when a dragged file has left the document,\n // hide all relevant drop zones the next time the mouse enters the document.\n // Note that mouse events such as this one are not fired during drag operations.\n disposeSupport.attach(qq(document).children()[0], \"mouseenter\", function(e) {\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, \"drop\", function(e) {\n e.preventDefault();\n maybeHideDropZones();\n });\n\n disposeSupport.attach(document, HIDE_ZONES_EVENT_NAME, maybeHideDropZones);\n }\n\n setupDragDrop();\n\n qq.extend(this, {\n setupExtraDropzone: function(element) {\n options.dropZoneElements.push(element);\n setupDropzone(element);\n },\n\n removeDropzone: function(element) {\n var i,\n dzs = options.dropZoneElements;\n\n for (i in dzs) {\n if (dzs[i] === element) {\n return dzs.splice(i, 1);\n }\n }\n },\n\n dispose: function() {\n disposeSupport.dispose();\n qq.each(uploadDropZones, function(idx, dropZone) {\n dropZone.dispose();\n });\n }\n });\n};\n\nqq.DragAndDrop.callbacks = function() {\n \"use strict\";\n\n return {\n processingDroppedFiles: function() {},\n processingDroppedFilesComplete: function(files, targetEl) {},\n dropError: function(code, errorSpecifics) {\n qq.log(\"Drag & drop error code '\" + code + \" with these specifics: '\" + errorSpecifics + \"'\", \"error\");\n },\n dropLog: function(message, level) {\n qq.log(message, level);\n }\n };\n};\n\nqq.UploadDropZone = function(o) {\n \"use strict\";\n\n var disposeSupport = new qq.DisposeSupport(),\n options, element, preventDrop, dropOutsideDisabled;\n\n options = {\n element: null,\n onEnter: function(e) {},\n onLeave: function(e) {},\n // is not fired when leaving element by hovering descendants\n onLeaveNotDescendants: function(e) {},\n onDrop: function(e) {}\n };\n\n qq.extend(options, o);\n element = options.element;\n\n function dragoverShouldBeCanceled() {\n return qq.safari() || (qq.firefox() && qq.windows());\n }\n\n function disableDropOutside(e) {\n // run only once for all instances\n if (!dropOutsideDisabled) {\n\n // for these cases we need to catch onDrop to reset dropArea\n if (dragoverShouldBeCanceled) {\n disposeSupport.attach(document, \"dragover\", function(e) {\n e.preventDefault();\n });\n } else {\n disposeSupport.attach(document, \"dragover\", function(e) {\n if (e.dataTransfer) {\n e.dataTransfer.dropEffect = \"none\";\n e.preventDefault();\n }\n });\n }\n\n dropOutsideDisabled = true;\n }\n }\n\n function isValidFileDrag(e) {\n // e.dataTransfer currently causing IE errors\n // IE9 does NOT support file API, so drag-and-drop is not possible\n if (!qq.supportedFeatures.fileDrop) {\n return false;\n }\n\n var effectTest, dt = e.dataTransfer,\n // do not check dt.types.contains in webkit, because it crashes safari 4\n isSafari = qq.safari();\n\n // dt.effectAllowed is none in Safari 5\n // dt.types.contains check is for firefox\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n effectTest = qq.ie() && qq.supportedFeatures.fileDrop ? true : dt.effectAllowed !== \"none\";\n return dt && effectTest && (dt.files || (!isSafari && dt.types.contains && dt.types.contains(\"Files\")));\n }\n\n function isOrSetDropDisabled(isDisabled) {\n if (isDisabled !== undefined) {\n preventDrop = isDisabled;\n }\n return preventDrop;\n }\n\n function triggerHidezonesEvent() {\n var hideZonesEvent;\n\n function triggerUsingOldApi() {\n hideZonesEvent = document.createEvent(\"Event\");\n hideZonesEvent.initEvent(options.HIDE_ZONES_EVENT_NAME, true, true);\n }\n\n if (window.CustomEvent) {\n try {\n hideZonesEvent = new CustomEvent(options.HIDE_ZONES_EVENT_NAME);\n }\n catch (err) {\n triggerUsingOldApi();\n }\n }\n else {\n triggerUsingOldApi();\n }\n\n document.dispatchEvent(hideZonesEvent);\n }\n\n function attachEvents() {\n disposeSupport.attach(element, \"dragover\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n // dt.effectAllowed crashes IE 11 & 10 when files have been dragged from\n // the filesystem\n var effect = qq.ie() && qq.supportedFeatures.fileDrop ? null : e.dataTransfer.effectAllowed;\n if (effect === \"move\" || effect === \"linkMove\") {\n e.dataTransfer.dropEffect = \"move\"; // for FF (only move allowed)\n } else {\n e.dataTransfer.dropEffect = \"copy\"; // for Chrome\n }\n\n e.stopPropagation();\n e.preventDefault();\n });\n\n disposeSupport.attach(element, \"dragenter\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n options.onEnter(e);\n }\n });\n\n disposeSupport.attach(element, \"dragleave\", function(e) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n options.onLeave(e);\n\n var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);\n // do not fire when moving a mouse over a descendant\n if (qq(this).contains(relatedTarget)) {\n return;\n }\n\n options.onLeaveNotDescendants(e);\n });\n\n disposeSupport.attach(element, \"drop\", function(e) {\n if (!isOrSetDropDisabled()) {\n if (!isValidFileDrag(e)) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n options.onDrop(e);\n\n triggerHidezonesEvent();\n }\n });\n }\n\n disableDropOutside();\n attachEvents();\n\n qq.extend(this, {\n dropDisabled: function(isDisabled) {\n return isOrSetDropDisabled(isDisabled);\n },\n\n dispose: function() {\n disposeSupport.dispose();\n },\n\n getElement: function() {\n return element;\n }\n });\n};\n"]} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/edit.gif b/styles/bootstrap/fine-uploader/edit.gif new file mode 100644 index 000000000..403e7c67d Binary files /dev/null and b/styles/bootstrap/fine-uploader/edit.gif differ diff --git a/styles/bootstrap/fine-uploader/fine-uploader-gallery.css b/styles/bootstrap/fine-uploader/fine-uploader-gallery.css new file mode 100644 index 000000000..bdcca3b4a --- /dev/null +++ b/styles/bootstrap/fine-uploader/fine-uploader-gallery.css @@ -0,0 +1,471 @@ +/* --------------------------------------- +/* Fine Uploader Gallery View Styles +/* --------------------------------------- + + +/* Buttons +------------------------------------------ */ +.qq-gallery .qq-btn +{ + float: right; + border: none; + padding: 0; + margin: 0; + box-shadow: none; +} + +/* Upload Button +------------------------------------------ */ +.qq-gallery .qq-upload-button { + display: inline; + width: 105px; + padding: 7px 10px; + float: left; + text-align: center; + background: #00ABC7; + color: #FFFFFF; + border-radius: 2px; + border: 1px solid #37B7CC; + box-shadow: 0 1px 1px rgba(255, 255, 255, 0.37) inset, + 1px 0 1px rgba(255, 255, 255, 0.07) inset, + 0 1px 0 rgba(0, 0, 0, 0.36), + 0 -2px 12px rgba(0, 0, 0, 0.08) inset +} +.qq-gallery .qq-upload-button-hover { + background: #33B6CC; +} +.qq-gallery .qq-upload-button-focus { + outline: 1px dotted #000000; +} + + +/* Drop Zone +------------------------------------------ */ +.qq-gallery.qq-uploader { + position: relative; + min-height: 200px; + max-height: 490px; + overflow-y: hidden; + width: inherit; + border-radius: 6px; + border: 1px dashed #CCCCCC; + background-color: #FAFAFA; + padding: 20px; +} +.qq-gallery.qq-uploader:before { + content: attr(qq-drop-area-text) " "; + position: absolute; + font-size: 200%; + left: 0; + width: 100%; + text-align: center; + top: 45%; + opacity: 0.25; + filter: alpha(opacity=25); +} +.qq-gallery .qq-upload-drop-area, .qq-upload-extra-drop-area { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + min-height: 30px; + z-index: 2; + background: #F9F9F9; + border-radius: 4px; + text-align: center; +} +.qq-gallery .qq-upload-drop-area span { + display: block; + position: absolute; + top: 50%; + width: 100%; + margin-top: -8px; + font-size: 16px; +} +.qq-gallery .qq-upload-extra-drop-area { + position: relative; + margin-top: 50px; + font-size: 16px; + padding-top: 30px; + height: 20px; + min-height: 40px; +} +.qq-gallery .qq-upload-drop-area-active { + background: #FDFDFD; + border-radius: 4px; +} +.qq-gallery .qq-upload-list { + margin: 0; + padding: 10px 0 0; + list-style: none; + max-height: 450px; + overflow-y: auto; + clear: both; + box-shadow: none; +} + + +/* Uploaded Elements +------------------------------------------ */ +.qq-gallery .qq-upload-list li { + display: inline-block; + position: relative; + max-width: 120px; + margin: 0 25px 25px 0; + padding: 0; + line-height: 16px; + font-size: 13px; + color: #424242; + background-color: #FFFFFF; + border-radius: 2px; + box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.22); + vertical-align: top; + + /* to ensure consistent size of tiles - may need to change if qq-max-size attr on preview img changes */ + height: 186px; +} + +.qq-gallery .qq-upload-spinner, +.qq-gallery .qq-upload-size, +.qq-gallery .qq-upload-retry, +.qq-gallery .qq-upload-failed-text, +.qq-gallery .qq-upload-delete, +.qq-gallery .qq-upload-pause, +.qq-gallery .qq-upload-continue { + display: inline; +} +.qq-gallery .qq-upload-retry:hover, +.qq-gallery .qq-upload-delete:hover, +.qq-gallery .qq-upload-pause:hover, +.qq-gallery .qq-upload-continue:hover { + background-color: transparent; +} +.qq-gallery .qq-upload-delete, +.qq-gallery .qq-upload-pause, +.qq-gallery .qq-upload-continue, +.qq-gallery .qq-upload-cancel { + cursor: pointer; +} +.qq-gallery .qq-upload-delete, +.qq-gallery .qq-upload-pause, +.qq-gallery .qq-upload-continue { + border:none; + background: none; + color: #00A0BA; + font-size: 12px; + padding: 0; +} +/* to ensure consistent size of tiles - only display status text before auto-retry or after failure */ +.qq-gallery .qq-upload-status-text { + color: #333333; + font-size: 12px; + padding-left: 3px; + padding-top: 2px; + width: inherit; + display: none; + width: 108px; +} +.qq-gallery .qq-upload-fail .qq-upload-status-text { + text-overflow: ellipsis; + white-space: nowrap; + overflow-x: hidden; + display: block; +} +.qq-gallery .qq-upload-retrying .qq-upload-status-text { + display: inline-block; +} +.qq-gallery .qq-upload-retrying .qq-progress-bar-container { + display: none; +} + +.qq-gallery .qq-upload-cancel { + background-color: #525252; + color: #F7F7F7; + font-weight: bold; + font-family: Arial, Helvetica, sans-serif; + border-radius: 12px; + border: none; + height: 22px; + width: 22px; + padding: 4px; + position: absolute; + right: -5px; + top: -6px; + margin: 0; + line-height: 17px; +} +.qq-gallery .qq-upload-cancel:hover { + background-color: #525252; +} +.qq-gallery .qq-upload-retry { + cursor: pointer; + position: absolute; + top: 30px; + left: 50%; + margin-left: -31px; + box-shadow: 0 1px 1px rgba(255, 255, 255, 0.37) inset, + 1px 0 1px rgba(255, 255, 255, 0.07) inset, + 0 4px 4px rgba(0, 0, 0, 0.5), + 0 -2px 12px rgba(0, 0, 0, 0.08) inset; + padding: 3px 4px; + border: 1px solid #d2ddc7; + border-radius: 2px; + color: inherit; + background-color: #EBF6E0; + z-index: 1; +} +.qq-gallery .qq-upload-retry:hover { + background-color: #f7ffec; +} + +.qq-gallery .qq-file-info { + padding: 10px 6px 4px; + margin-top: -3px; + border-radius: 0 0 2px 2px; + text-align: left; + overflow: hidden; +} + +.qq-gallery .qq-file-info .qq-file-name { + position: relative; +} + +.qq-gallery .qq-upload-file { + display: block; + margin-right: 0; + margin-bottom: 3px; + width: auto; + + /* to ensure consistent size of tiles - constrain text to single line */ + text-overflow: ellipsis; + white-space: nowrap; + overflow-x: hidden; +} +.qq-gallery .qq-upload-spinner { + display: inline-block; + background: url("loading.gif"); + position: absolute; + left: 50%; + margin-left: -7px; + top: 53px; + width: 15px; + height: 15px; + vertical-align: text-bottom; +} +.qq-gallery .qq-drop-processing { + display: block; +} +.qq-gallery .qq-drop-processing-spinner { + display: inline-block; + background: url("processing.gif"); + width: 24px; + height: 24px; + vertical-align: text-bottom; +} +.qq-gallery .qq-upload-failed-text { + display: none; + font-style: italic; + font-weight: bold; +} +.qq-gallery .qq-upload-failed-icon { + display:none; + width:15px; + height:15px; + vertical-align:text-bottom; +} +.qq-gallery .qq-upload-fail .qq-upload-failed-text { + display: inline; +} +.qq-gallery .qq-upload-retrying .qq-upload-failed-text { + display: inline; +} +.qq-gallery .qq-upload-list li.qq-upload-success { + background-color: #F2F7ED; +} +.qq-gallery .qq-upload-list li.qq-upload-fail { + background-color: #F5EDED; + box-shadow: 0 0 1px 0 red; + border: 0; +} +.qq-gallery .qq-progress-bar { + display: block; + background: #00abc7; + width: 0%; + height: 15px; + border-radius: 6px; + margin-bottom: 3px; +} + +.qq-gallery .qq-total-progress-bar { + height: 25px; + border-radius: 9px; +} + +.qq-gallery .qq-total-progress-bar-container { + margin-left: 9px; + display: inline; + float: right; + width: 500px; +} + +.qq-gallery .qq-upload-size { + float: left; + font-size: 11px; + color: #929292; + margin-bottom: 3px; + margin-right: 0; + display: inline-block; +} + +.qq-gallery INPUT.qq-edit-filename { + position: absolute; + opacity: 0; + filter: alpha(opacity=0); + z-index: -1; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; +} + +.qq-gallery .qq-upload-file.qq-editable { + cursor: pointer; + margin-right: 20px; +} + +.qq-gallery .qq-edit-filename-icon.qq-editable { + display: inline-block; + cursor: pointer; + position: absolute; + right: 0; + top: 0; +} + +.qq-gallery INPUT.qq-edit-filename.qq-editing { + position: static; + height: 28px; + width: 90px; + width: -moz-available; + padding: 0 8px; + margin-bottom: 3px; + border: 1px solid #ccc; + border-radius: 2px; + font-size: 13px; + + opacity: 1; + filter: alpha(opacity=100); + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +} + +.qq-gallery .qq-edit-filename-icon { + display: none; + background: url("edit.gif"); + width: 15px; + height: 15px; + vertical-align: text-bottom; +} +.qq-gallery .qq-delete-icon { + background: url("trash.gif"); + width: 15px; + height: 15px; + vertical-align: sub; + display: inline-block; +} +.qq-gallery .qq-retry-icon { + background: url("retry.gif"); + width: 15px; + height: 15px; + vertical-align: sub; + display: inline-block; + float: none; +} +.qq-gallery .qq-continue-icon { + background: url("continue.gif"); + width: 15px; + height: 15px; + vertical-align: sub; + display: inline-block; +} +.qq-gallery .qq-pause-icon { + background: url("pause.gif"); + width: 15px; + height: 15px; + vertical-align: sub; + display: inline-block; +} + +.qq-gallery .qq-hide { + display: none; +} + + +/* Thumbnail +------------------------------------------ */ +.qq-gallery .qq-in-progress .qq-thumbnail-wrapper { + /* makes the spinner on top of the thumbnail more visible */ + opacity: 0.5; + filter: alpha(opacity=50); +} +.qq-gallery .qq-thumbnail-wrapper { + overflow: hidden; + position: relative; + + /* to ensure consistent size of tiles - should match qq-max-size attribute value on qq-thumbnail-selector IMG element */ + height: 120px; + width: 120px; +} +.qq-gallery .qq-thumbnail-selector { + border-radius: 2px 2px 0 0; + bottom: 0; + + /* we will override this in the :root thumbnail selector (to help center the preview) for everything other than IE8 */ + top: 0; + + /* center the thumb horizontally in the tile */ + margin:auto; + display: block; +} + +/* hack to ensure we don't try to center preview in IE8, since -ms-filter doesn't mimic translateY as expected in all cases */ +:root *> .qq-gallery .qq-thumbnail-selector { + /* vertically center preview image on tile */ + position: relative; + top: 50%; + transform: translateY(-50%); + -moz-transform: translateY(-50%); + -ms-transform: translateY(-50%); + -webkit-transform: translateY(-50%); +} + +/* element styles */ +.qq-gallery.qq-uploader DIALOG { + display: none; +} + +.qq-gallery.qq-uploader DIALOG[open] { + display: block; +} + +.qq-gallery.qq-uploader DIALOG { + display: none; +} + +.qq-gallery.qq-uploader DIALOG[open] { + display: block; +} + +.qq-gallery.qq-uploader DIALOG .qq-dialog-buttons { + text-align: center; + padding-top: 10px; +} + +.qq-gallery.qq-uploader DIALOG .qq-dialog-buttons BUTTON { + margin-left: 5px; + margin-right: 5px; +} + +.qq-gallery.qq-uploader DIALOG .qq-dialog-message-selector { + padding-bottom: 10px; +} + +.qq-gallery .qq-uploader DIALOG::backdrop { + background-color: rgba(0, 0, 0, 0.7); +} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader-gallery.min.css b/styles/bootstrap/fine-uploader/fine-uploader-gallery.min.css new file mode 100644 index 000000000..4e3a3b075 --- /dev/null +++ b/styles/bootstrap/fine-uploader/fine-uploader-gallery.min.css @@ -0,0 +1 @@ +.qq-gallery .qq-btn{float:right;border:none;padding:0;margin:0;box-shadow:none}.qq-gallery .qq-upload-button{display:inline;width:105px;padding:7px 10px;float:left;text-align:center;background:#00ABC7;color:#FFF;border-radius:2px;border:1px solid #37B7CC;box-shadow:0 1px 1px rgba(255,255,255,.37) inset,1px 0 1px rgba(255,255,255,.07) inset,0 1px 0 rgba(0,0,0,.36),0 -2px 12px rgba(0,0,0,.08) inset}.qq-gallery .qq-upload-button-hover{background:#33B6CC}.qq-gallery .qq-upload-button-focus{outline:#000 dotted 1px}.qq-gallery.qq-uploader{position:relative;min-height:200px;max-height:490px;overflow-y:hidden;width:inherit;border-radius:6px;border:1px dashed #CCC;background-color:#FAFAFA;padding:20px}.qq-gallery.qq-uploader:before{content:attr(qq-drop-area-text) " ";position:absolute;font-size:200%;left:0;width:100%;text-align:center;top:45%;opacity:.25;filter:alpha(opacity=25)}.qq-gallery .qq-upload-drop-area,.qq-upload-extra-drop-area{position:absolute;top:0;left:0;width:100%;height:100%;min-height:30px;z-index:2;background:#F9F9F9;border-radius:4px;text-align:center}.qq-gallery .qq-upload-drop-area span{display:block;position:absolute;top:50%;width:100%;margin-top:-8px;font-size:16px}.qq-gallery .qq-upload-extra-drop-area{position:relative;margin-top:50px;font-size:16px;padding-top:30px;height:20px;min-height:40px}.qq-gallery .qq-upload-drop-area-active{background:#FDFDFD;border-radius:4px}.qq-gallery .qq-upload-list{margin:0;padding:10px 0 0;list-style:none;max-height:450px;overflow-y:auto;clear:both;box-shadow:none}.qq-gallery .qq-upload-list li{display:inline-block;position:relative;max-width:120px;margin:0 25px 25px 0;padding:0;line-height:16px;font-size:13px;color:#424242;background-color:#FFF;border-radius:2px;box-shadow:0 1px 1px 0 rgba(0,0,0,.22);vertical-align:top;height:186px}.qq-gallery .qq-upload-continue,.qq-gallery .qq-upload-delete,.qq-gallery .qq-upload-failed-text,.qq-gallery .qq-upload-pause,.qq-gallery .qq-upload-retry,.qq-gallery .qq-upload-size,.qq-gallery .qq-upload-spinner{display:inline}.qq-gallery .qq-upload-continue:hover,.qq-gallery .qq-upload-delete:hover,.qq-gallery .qq-upload-pause:hover,.qq-gallery .qq-upload-retry:hover{background-color:transparent}.qq-gallery .qq-upload-cancel,.qq-gallery .qq-upload-continue,.qq-gallery .qq-upload-delete,.qq-gallery .qq-upload-pause{cursor:pointer}.qq-gallery .qq-upload-continue,.qq-gallery .qq-upload-delete,.qq-gallery .qq-upload-pause{border:none;background:0 0;color:#00A0BA;font-size:12px;padding:0}.qq-gallery .qq-upload-status-text{color:#333;font-size:12px;padding-left:3px;padding-top:2px;display:none;width:108px}.qq-gallery .qq-upload-fail .qq-upload-status-text{text-overflow:ellipsis;white-space:nowrap;overflow-x:hidden;display:block}.qq-gallery .qq-upload-retrying .qq-upload-status-text{display:inline-block}.qq-gallery .qq-upload-retrying .qq-progress-bar-container{display:none}.qq-gallery .qq-upload-cancel{background-color:#525252;color:#F7F7F7;font-weight:700;font-family:Arial,Helvetica,sans-serif;border-radius:12px;border:none;height:22px;width:22px;padding:4px;position:absolute;right:-5px;top:-6px;margin:0;line-height:17px}.qq-gallery .qq-upload-cancel:hover{background-color:#525252}.qq-gallery .qq-upload-retry{cursor:pointer;position:absolute;top:30px;left:50%;margin-left:-31px;box-shadow:0 1px 1px rgba(255,255,255,.37) inset,1px 0 1px rgba(255,255,255,.07) inset,0 4px 4px rgba(0,0,0,.5),0 -2px 12px rgba(0,0,0,.08) inset;padding:3px 4px;border:1px solid #d2ddc7;border-radius:2px;color:inherit;background-color:#EBF6E0;z-index:1}.qq-gallery .qq-upload-retry:hover{background-color:#f7ffec}.qq-gallery .qq-file-info{padding:10px 6px 4px;margin-top:-3px;border-radius:0 0 2px 2px;text-align:left;overflow:hidden}.qq-gallery .qq-file-info .qq-file-name{position:relative}.qq-gallery .qq-upload-file{display:block;margin-right:0;margin-bottom:3px;width:auto;text-overflow:ellipsis;white-space:nowrap;overflow-x:hidden}.qq-gallery .qq-upload-spinner{display:inline-block;background:url(loading.gif);position:absolute;left:50%;margin-left:-7px;top:53px;width:15px;height:15px;vertical-align:text-bottom}.qq-gallery .qq-drop-processing{display:block}.qq-gallery .qq-drop-processing-spinner{display:inline-block;background:url(processing.gif);width:24px;height:24px;vertical-align:text-bottom}.qq-gallery .qq-upload-failed-text{display:none;font-style:italic;font-weight:700}.qq-gallery .qq-upload-failed-icon{display:none;width:15px;height:15px;vertical-align:text-bottom}.qq-gallery .qq-upload-fail .qq-upload-failed-text,.qq-gallery .qq-upload-retrying .qq-upload-failed-text{display:inline}.qq-gallery .qq-upload-list li.qq-upload-success{background-color:#F2F7ED}.qq-gallery .qq-upload-list li.qq-upload-fail{background-color:#F5EDED;box-shadow:0 0 1px 0 red;border:0}.qq-gallery .qq-progress-bar{display:block;background:#00abc7;width:0;height:15px;border-radius:6px;margin-bottom:3px}.qq-gallery .qq-total-progress-bar{height:25px;border-radius:9px}.qq-gallery .qq-total-progress-bar-container{margin-left:9px;display:inline;float:right;width:500px}.qq-gallery .qq-upload-size{float:left;font-size:11px;color:#929292;margin-bottom:3px;margin-right:0;display:inline-block}.qq-gallery INPUT.qq-edit-filename{position:absolute;opacity:0;filter:alpha(opacity=0);z-index:-1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"}.qq-gallery .qq-upload-file.qq-editable{cursor:pointer;margin-right:20px}.qq-gallery .qq-edit-filename-icon.qq-editable{display:inline-block;cursor:pointer;position:absolute;right:0;top:0}.qq-gallery INPUT.qq-edit-filename.qq-editing{position:static;height:28px;width:90px;width:-moz-available;padding:0 8px;margin-bottom:3px;border:1px solid #ccc;border-radius:2px;font-size:13px;opacity:1;filter:alpha(opacity=100);-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}.qq-gallery .qq-edit-filename-icon{display:none;background:url(edit.gif);width:15px;height:15px;vertical-align:text-bottom}.qq-gallery .qq-continue-icon,.qq-gallery .qq-delete-icon,.qq-gallery .qq-pause-icon,.qq-gallery .qq-retry-icon{width:15px;height:15px;vertical-align:sub;display:inline-block}.qq-gallery .qq-delete-icon{background:url(trash.gif)}.qq-gallery .qq-retry-icon{background:url(retry.gif);float:none}.qq-gallery .qq-continue-icon{background:url(continue.gif)}.qq-gallery .qq-pause-icon{background:url(pause.gif)}.qq-gallery .qq-hide{display:none}.qq-gallery .qq-in-progress .qq-thumbnail-wrapper{opacity:.5;filter:alpha(opacity=50)}.qq-gallery .qq-thumbnail-wrapper{overflow:hidden;position:relative;height:120px;width:120px}.qq-gallery .qq-thumbnail-selector{border-radius:2px 2px 0 0;bottom:0;top:0;margin:auto;display:block}:root *>.qq-gallery .qq-thumbnail-selector{position:relative;top:50%;transform:translateY(-50%);-moz-transform:translateY(-50%);-ms-transform:translateY(-50%);-webkit-transform:translateY(-50%)}.qq-gallery.qq-uploader DIALOG{display:none}.qq-gallery.qq-uploader DIALOG[open]{display:block}.qq-gallery.qq-uploader DIALOG .qq-dialog-buttons{text-align:center;padding-top:10px}.qq-gallery.qq-uploader DIALOG .qq-dialog-buttons BUTTON{margin-left:5px;margin-right:5px}.qq-gallery.qq-uploader DIALOG .qq-dialog-message-selector{padding-bottom:10px}.qq-gallery .qq-uploader DIALOG::backdrop{background-color:rgba(0,0,0,.7)}/*# sourceMappingURL=fine-uploader-gallery.min.css.map */ \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader-gallery.min.css.map b/styles/bootstrap/fine-uploader/fine-uploader-gallery.min.css.map new file mode 100644 index 000000000..41f0bbeb0 --- /dev/null +++ b/styles/bootstrap/fine-uploader/fine-uploader-gallery.min.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["_build/fine-uploader-gallery.css"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader-new.css b/styles/bootstrap/fine-uploader/fine-uploader-new.css new file mode 100644 index 000000000..c7678a3b0 --- /dev/null +++ b/styles/bootstrap/fine-uploader/fine-uploader-new.css @@ -0,0 +1,354 @@ +/* --------------------------------------- +/* Fine Uploader Styles +/* --------------------------------------- + +/* Buttons +------------------------------------------ */ +.qq-btn +{ + box-shadow: 0 1px 1px rgba(255, 255, 255, 0.37) inset, + 1px 0 1px rgba(255, 255, 255, 0.07) inset, + 0 1px 0 rgba(0, 0, 0, 0.36), + 0 -2px 12px rgba(0, 0, 0, 0.08) inset; + padding: 3px 4px; + border: 1px solid #CCCCCC; + border-radius: 2px; + color: inherit; + background-color: #FFFFFF; +} +.qq-upload-delete, .qq-upload-pause, .qq-upload-continue { + display: inline; +} +.qq-upload-delete +{ + background-color: #e65c47; + color: #FAFAFA; + border-color: #dc523d; + text-shadow: 0 1px 1px rgba(0, 0, 0, 0.55); +} +.qq-upload-delete:hover { + background-color: #f56b56; + } +.qq-upload-cancel +{ + background-color: #F5D7D7; + border-color: #e6c8c8; +} +.qq-upload-cancel:hover { + background-color: #ffe1e1; +} +.qq-upload-retry +{ + background-color: #EBF6E0; + border-color: #d2ddc7; +} +.qq-upload-retry:hover { + background-color: #f7ffec; +} +.qq-upload-pause, .qq-upload-continue { + background-color: #00ABC7; + color: #FAFAFA; + border-color: #2dadc2; + text-shadow: 0 1px 1px rgba(0, 0, 0, 0.55); +} +.qq-upload-pause:hover, .qq-upload-continue:hover { + background-color: #0fbad6; +} + +/* Upload Button +------------------------------------------ */ +.qq-upload-button { + display: inline; + width: 105px; + margin-bottom: 10px; + padding: 7px 10px; + text-align: center; + float: left; + background: #00ABC7; + color: #FFFFFF; + border-radius: 2px; + border: 1px solid #2dadc2; + box-shadow: 0 1px 1px rgba(255, 255, 255, 0.37) inset, + 1px 0 1px rgba(255, 255, 255, 0.07) inset, + 0 1px 0 rgba(0, 0, 0, 0.36), + 0 -2px 12px rgba(0, 0, 0, 0.08) inset; +} +.qq-upload-button-hover { + background: #33B6CC; +} +.qq-upload-button-focus { + outline: 1px dotted #000000; +} + + +/* Drop Zone +------------------------------------------ */ +.qq-uploader { + position: relative; + min-height: 200px; + max-height: 490px; + overflow-y: hidden; + width: inherit; + border-radius: 6px; + background-color: #FDFDFD; + border: 1px dashed #CCCCCC; + padding: 20px; +} +.qq-uploader:before { + content: attr(qq-drop-area-text) " "; + position: absolute; + font-size: 200%; + left: 0; + width: 100%; + text-align: center; + top: 45%; + opacity: 0.25; +} +.qq-upload-drop-area, .qq-upload-extra-drop-area { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + min-height: 30px; + z-index: 2; + background: #F9F9F9; + border-radius: 4px; + border: 1px dashed #CCCCCC; + text-align: center; +} +.qq-upload-drop-area span { + display: block; + position: absolute; + top: 50%; + width: 100%; + margin-top: -8px; + font-size: 16px; +} +.qq-upload-extra-drop-area { + position: relative; + margin-top: 50px; + font-size: 16px; + padding-top: 30px; + height: 20px; + min-height: 40px; +} +.qq-upload-drop-area-active { + background: #FDFDFD; + border-radius: 4px; + border: 1px dashed #CCCCCC; +} +.qq-upload-list { + margin: 0; + padding: 0; + list-style: none; + max-height: 450px; + overflow-y: auto; + box-shadow: 0px 1px 0px rgba(15, 15, 50, 0.14); + clear: both; +} + + +/* Uploaded Elements +------------------------------------------ */ +.qq-upload-list li { + margin: 0; + padding: 9px; + line-height: 15px; + font-size: 16px; + color: #424242; + background-color: #F6F6F6; + border-top: 1px solid #FFFFFF; + border-bottom: 1px solid #DDDDDD; +} +.qq-upload-list li:first-child { + border-top: none; +} +.qq-upload-list li:last-child { + border-bottom: none; +} + +.qq-upload-file, .qq-upload-spinner, .qq-upload-size, +.qq-upload-cancel, .qq-upload-retry, .qq-upload-failed-text, +.qq-upload-delete, .qq-upload-pause, .qq-upload-continue { + margin-right: 12px; + display: inline; +} +.qq-upload-file { + vertical-align: middle; + display: inline-block; + width: 300px; + text-overflow: ellipsis; + white-space: nowrap; + overflow-x: hidden; + height: 18px; +} +.qq-upload-spinner { + display: inline-block; + background: url("loading.gif"); + width: 15px; + height: 15px; + vertical-align: text-bottom; +} +.qq-drop-processing { + display: block; +} +.qq-drop-processing-spinner { + display: inline-block; + background: url("processing.gif"); + width: 24px; + height: 24px; + vertical-align: text-bottom; +} +.qq-upload-size, .qq-upload-cancel, .qq-upload-retry, +.qq-upload-delete, .qq-upload-pause, .qq-upload-continue { + font-size: 12px; + font-weight: normal; + cursor: pointer; + vertical-align: middle; +} +.qq-upload-status-text { + font-size: 14px; + font-weight: bold; + display: block; +} +.qq-upload-failed-text { + display: none; + font-style: italic; + font-weight: bold; +} +.qq-upload-failed-icon { + display:none; + width:15px; + height:15px; + vertical-align:text-bottom; +} +.qq-upload-fail .qq-upload-failed-text { + display: inline; +} +.qq-upload-retrying .qq-upload-failed-text { + display: inline; +} +.qq-upload-list li.qq-upload-success { + background-color: #EBF6E0; + color: #424242; + border-bottom: 1px solid #D3DED1; + border-top: 1px solid #F7FFF5; +} +.qq-upload-list li.qq-upload-fail { + background-color: #F5D7D7; + color: #424242; + border-bottom: 1px solid #DECACA; + border-top: 1px solid #FCE6E6; +} +.qq-progress-bar { + display: block; + display: block; + background: #00abc7; + width: 0%; + height: 15px; + border-radius: 6px; + margin-bottom: 3px; +} + +.qq-total-progress-bar { + height: 25px; + border-radius: 9px; +} + +.qq-total-progress-bar-container { + margin-left: 9px; + display: inline; + float: right; + width: 500px; +} + +INPUT.qq-edit-filename { + position: absolute; + opacity: 0; + filter: alpha(opacity=0); + z-index: -1; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; +} + +.qq-upload-file.qq-editable { + cursor: pointer; + margin-right: 4px; +} + +.qq-edit-filename-icon.qq-editable { + display: inline-block; + cursor: pointer; +} + +INPUT.qq-edit-filename.qq-editing { + position: static; + height: 28px; + padding: 0 8px; + margin-right: 10px; + margin-bottom: -5px; + border: 1px solid #ccc; + border-radius: 2px; + font-size: 16px; + + opacity: 1; + filter: alpha(opacity=100); + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; +} + +.qq-edit-filename-icon { + display: none; + background: url("edit.gif"); + width: 15px; + height: 15px; + vertical-align: text-bottom; + margin-right: 16px; +} + +.qq-hide { + display: none; +} + + +/* Thumbnail +------------------------------------------ */ +.qq-thumbnail-selector { + vertical-align: middle; + margin-right: 12px; +} + + +/* element styles */ +.qq-uploader DIALOG { + display: none; +} + +.qq-uploader DIALOG[open] { + display: block; +} + +.qq-uploader DIALOG { + display: none; +} + +.qq-uploader DIALOG[open] { + display: block; +} + +.qq-uploader DIALOG .qq-dialog-buttons { + text-align: center; + padding-top: 10px; +} + +.qq-uploader DIALOG .qq-dialog-buttons BUTTON { + margin-left: 5px; + margin-right: 5px; +} + +.qq-uploader DIALOG .qq-dialog-message-selector { + padding-bottom: 10px; +} + +.qq-uploader DIALOG::backdrop { + background-color: rgba(0, 0, 0, 0.7); +} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader-new.min.css b/styles/bootstrap/fine-uploader/fine-uploader-new.min.css new file mode 100644 index 000000000..58422f2f6 --- /dev/null +++ b/styles/bootstrap/fine-uploader/fine-uploader-new.min.css @@ -0,0 +1 @@ +.qq-btn,.qq-upload-button{box-shadow:0 1px 1px rgba(255,255,255,.37) inset,1px 0 1px rgba(255,255,255,.07) inset,0 1px 0 rgba(0,0,0,.36),0 -2px 12px rgba(0,0,0,.08) inset}.qq-btn{padding:3px 4px;border:1px solid #CCC;border-radius:2px;color:inherit;background-color:#FFF}.qq-upload-delete{background-color:#e65c47;color:#FAFAFA;border-color:#dc523d;text-shadow:0 1px 1px rgba(0,0,0,.55)}.qq-upload-delete:hover{background-color:#f56b56}.qq-upload-cancel{background-color:#F5D7D7;border-color:#e6c8c8}.qq-upload-cancel:hover{background-color:#ffe1e1}.qq-upload-retry{background-color:#EBF6E0;border-color:#d2ddc7}.qq-upload-retry:hover{background-color:#f7ffec}.qq-upload-continue,.qq-upload-pause{background-color:#00ABC7;color:#FAFAFA;border-color:#2dadc2;text-shadow:0 1px 1px rgba(0,0,0,.55)}.qq-upload-continue:hover,.qq-upload-pause:hover{background-color:#0fbad6}.qq-upload-button{display:inline;width:105px;margin-bottom:10px;padding:7px 10px;text-align:center;float:left;background:#00ABC7;color:#FFF;border-radius:2px;border:1px solid #2dadc2}.qq-upload-button-hover{background:#33B6CC}.qq-upload-button-focus{outline:#000 dotted 1px}.qq-uploader{position:relative;min-height:200px;max-height:490px;overflow-y:hidden;width:inherit;border-radius:6px;background-color:#FDFDFD;border:1px dashed #CCC;padding:20px}.qq-uploader:before{content:attr(qq-drop-area-text) " ";position:absolute;font-size:200%;left:0;width:100%;text-align:center;top:45%;opacity:.25}.qq-upload-drop-area,.qq-upload-extra-drop-area{position:absolute;top:0;left:0;width:100%;height:100%;min-height:30px;z-index:2;background:#F9F9F9;border-radius:4px;border:1px dashed #CCC;text-align:center}.qq-upload-drop-area span{display:block;position:absolute;top:50%;width:100%;margin-top:-8px;font-size:16px}.qq-upload-extra-drop-area{position:relative;margin-top:50px;font-size:16px;padding-top:30px;height:20px;min-height:40px}.qq-upload-drop-area-active{background:#FDFDFD;border-radius:4px;border:1px dashed #CCC}.qq-upload-list{margin:0;padding:0;list-style:none;max-height:450px;overflow-y:auto;box-shadow:0 1px 0 rgba(15,15,50,.14);clear:both}.qq-upload-list li{margin:0;padding:9px;line-height:15px;font-size:16px;color:#424242;background-color:#F6F6F6;border-top:1px solid #FFF;border-bottom:1px solid #DDD}.qq-upload-list li:first-child{border-top:none}.qq-upload-list li:last-child{border-bottom:none}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-failed-text,.qq-upload-file,.qq-upload-pause,.qq-upload-retry,.qq-upload-size,.qq-upload-spinner{margin-right:12px;display:inline}.qq-upload-file{vertical-align:middle;display:inline-block;width:300px;text-overflow:ellipsis;white-space:nowrap;overflow-x:hidden;height:18px}.qq-upload-spinner{display:inline-block;background:url(loading.gif);width:15px;height:15px;vertical-align:text-bottom}.qq-drop-processing{display:block}.qq-drop-processing-spinner{display:inline-block;background:url(processing.gif);width:24px;height:24px;vertical-align:text-bottom}.qq-upload-cancel,.qq-upload-continue,.qq-upload-delete,.qq-upload-pause,.qq-upload-retry,.qq-upload-size{font-size:12px;font-weight:400;cursor:pointer;vertical-align:middle}.qq-upload-status-text{font-size:14px;font-weight:700;display:block}.qq-upload-failed-text{display:none;font-style:italic;font-weight:700}.qq-upload-failed-icon{display:none;width:15px;height:15px;vertical-align:text-bottom}.qq-upload-fail .qq-upload-failed-text,.qq-upload-retrying .qq-upload-failed-text{display:inline}.qq-upload-list li.qq-upload-success{background-color:#EBF6E0;color:#424242;border-bottom:1px solid #D3DED1;border-top:1px solid #F7FFF5}.qq-upload-list li.qq-upload-fail{background-color:#F5D7D7;color:#424242;border-bottom:1px solid #DECACA;border-top:1px solid #FCE6E6}.qq-progress-bar{display:block;background:#00abc7;width:0;height:15px;border-radius:6px;margin-bottom:3px}.qq-total-progress-bar{height:25px;border-radius:9px}.qq-total-progress-bar-container{margin-left:9px;display:inline;float:right;width:500px}INPUT.qq-edit-filename{position:absolute;opacity:0;filter:alpha(opacity=0);z-index:-1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"}.qq-upload-file.qq-editable{cursor:pointer;margin-right:4px}.qq-edit-filename-icon.qq-editable{display:inline-block;cursor:pointer}.qq-hide,.qq-uploader DIALOG{display:none}INPUT.qq-edit-filename.qq-editing{position:static;height:28px;padding:0 8px;margin-right:10px;margin-bottom:-5px;border:1px solid #ccc;border-radius:2px;font-size:16px;opacity:1;filter:alpha(opacity=100);-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}.qq-edit-filename-icon{display:none;background:url(edit.gif);width:15px;height:15px;vertical-align:text-bottom;margin-right:16px}.qq-thumbnail-selector{vertical-align:middle;margin-right:12px}.qq-uploader DIALOG[open]{display:block}.qq-uploader DIALOG .qq-dialog-buttons{text-align:center;padding-top:10px}.qq-uploader DIALOG .qq-dialog-buttons BUTTON{margin-left:5px;margin-right:5px}.qq-uploader DIALOG .qq-dialog-message-selector{padding-bottom:10px}.qq-uploader DIALOG::backdrop{background-color:rgba(0,0,0,.7)}/*# sourceMappingURL=fine-uploader-new.min.css.map */ \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader-new.min.css.map b/styles/bootstrap/fine-uploader/fine-uploader-new.min.css.map new file mode 100644 index 000000000..2dab29aa6 --- /dev/null +++ b/styles/bootstrap/fine-uploader/fine-uploader-new.min.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["_build/fine-uploader-new.css"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/styles/bootstrap/fine-uploader/fine-uploader.core.js b/styles/bootstrap/fine-uploader/fine-uploader.core.js new file mode 100644 index 000000000..3a6c70071 --- /dev/null +++ b/styles/bootstrap/fine-uploader/fine-uploader.core.js @@ -0,0 +1,5515 @@ +// Fine Uploader 5.12.0 - (c) 2013-present Widen Enterprises, Inc. MIT licensed. http://fineuploader.com +(function(global) { + var qq = function(element) { + "use strict"; + return { + hide: function() { + element.style.display = "none"; + return this; + }, + attach: function(type, fn) { + if (element.addEventListener) { + element.addEventListener(type, fn, false); + } else if (element.attachEvent) { + element.attachEvent("on" + type, fn); + } + return function() { + qq(element).detach(type, fn); + }; + }, + detach: function(type, fn) { + if (element.removeEventListener) { + element.removeEventListener(type, fn, false); + } else if (element.attachEvent) { + element.detachEvent("on" + type, fn); + } + return this; + }, + contains: function(descendant) { + if (!descendant) { + return false; + } + if (element === descendant) { + return true; + } + if (element.contains) { + return element.contains(descendant); + } else { + return !!(descendant.compareDocumentPosition(element) & 8); + } + }, + insertBefore: function(elementB) { + elementB.parentNode.insertBefore(element, elementB); + return this; + }, + remove: function() { + element.parentNode.removeChild(element); + return this; + }, + css: function(styles) { + if (element.style == null) { + throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!"); + } + if (styles.opacity != null) { + if (typeof element.style.opacity !== "string" && typeof element.filters !== "undefined") { + styles.filter = "alpha(opacity=" + Math.round(100 * styles.opacity) + ")"; + } + } + qq.extend(element.style, styles); + return this; + }, + hasClass: function(name, considerParent) { + var re = new RegExp("(^| )" + name + "( |$)"); + return re.test(element.className) || !!(considerParent && re.test(element.parentNode.className)); + }, + addClass: function(name) { + if (!qq(element).hasClass(name)) { + element.className += " " + name; + } + return this; + }, + removeClass: function(name) { + var re = new RegExp("(^| )" + name + "( |$)"); + element.className = element.className.replace(re, " ").replace(/^\s+|\s+$/g, ""); + return this; + }, + getByClass: function(className, first) { + var candidates, result = []; + if (first && element.querySelector) { + return element.querySelector("." + className); + } else if (element.querySelectorAll) { + return element.querySelectorAll("." + className); + } + candidates = element.getElementsByTagName("*"); + qq.each(candidates, function(idx, val) { + if (qq(val).hasClass(className)) { + result.push(val); + } + }); + return first ? result[0] : result; + }, + getFirstByClass: function(className) { + return qq(element).getByClass(className, true); + }, + children: function() { + var children = [], child = element.firstChild; + while (child) { + if (child.nodeType === 1) { + children.push(child); + } + child = child.nextSibling; + } + return children; + }, + setText: function(text) { + element.innerText = text; + element.textContent = text; + return this; + }, + clearText: function() { + return qq(element).setText(""); + }, + hasAttribute: function(attrName) { + var attrVal; + if (element.hasAttribute) { + if (!element.hasAttribute(attrName)) { + return false; + } + return /^false$/i.exec(element.getAttribute(attrName)) == null; + } else { + attrVal = element[attrName]; + if (attrVal === undefined) { + return false; + } + return /^false$/i.exec(attrVal) == null; + } + } + }; + }; + (function() { + "use strict"; + qq.canvasToBlob = function(canvas, mime, quality) { + return qq.dataUriToBlob(canvas.toDataURL(mime, quality)); + }; + qq.dataUriToBlob = function(dataUri) { + var arrayBuffer, byteString, createBlob = function(data, mime) { + var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder, blobBuilder = BlobBuilder && new BlobBuilder(); + if (blobBuilder) { + blobBuilder.append(data); + return blobBuilder.getBlob(mime); + } else { + return new Blob([ data ], { + type: mime + }); + } + }, intArray, mimeString; + if (dataUri.split(",")[0].indexOf("base64") >= 0) { + byteString = atob(dataUri.split(",")[1]); + } else { + byteString = decodeURI(dataUri.split(",")[1]); + } + mimeString = dataUri.split(",")[0].split(":")[1].split(";")[0]; + arrayBuffer = new ArrayBuffer(byteString.length); + intArray = new Uint8Array(arrayBuffer); + qq.each(byteString, function(idx, character) { + intArray[idx] = character.charCodeAt(0); + }); + return createBlob(arrayBuffer, mimeString); + }; + qq.log = function(message, level) { + if (window.console) { + if (!level || level === "info") { + window.console.log(message); + } else { + if (window.console[level]) { + window.console[level](message); + } else { + window.console.log("<" + level + "> " + message); + } + } + } + }; + qq.isObject = function(variable) { + return variable && !variable.nodeType && Object.prototype.toString.call(variable) === "[object Object]"; + }; + qq.isFunction = function(variable) { + return typeof variable === "function"; + }; + qq.isArray = function(value) { + return Object.prototype.toString.call(value) === "[object Array]" || value && window.ArrayBuffer && value.buffer && value.buffer.constructor === ArrayBuffer; + }; + qq.isItemList = function(maybeItemList) { + return Object.prototype.toString.call(maybeItemList) === "[object DataTransferItemList]"; + }; + qq.isNodeList = function(maybeNodeList) { + return Object.prototype.toString.call(maybeNodeList) === "[object NodeList]" || maybeNodeList.item && maybeNodeList.namedItem; + }; + qq.isString = function(maybeString) { + return Object.prototype.toString.call(maybeString) === "[object String]"; + }; + qq.trimStr = function(string) { + if (String.prototype.trim) { + return string.trim(); + } + return string.replace(/^\s+|\s+$/g, ""); + }; + qq.format = function(str) { + var args = Array.prototype.slice.call(arguments, 1), newStr = str, nextIdxToReplace = newStr.indexOf("{}"); + qq.each(args, function(idx, val) { + var strBefore = newStr.substring(0, nextIdxToReplace), strAfter = newStr.substring(nextIdxToReplace + 2); + newStr = strBefore + val + strAfter; + nextIdxToReplace = newStr.indexOf("{}", nextIdxToReplace + val.length); + if (nextIdxToReplace < 0) { + return false; + } + }); + return newStr; + }; + qq.isFile = function(maybeFile) { + return window.File && Object.prototype.toString.call(maybeFile) === "[object File]"; + }; + qq.isFileList = function(maybeFileList) { + return window.FileList && Object.prototype.toString.call(maybeFileList) === "[object FileList]"; + }; + qq.isFileOrInput = function(maybeFileOrInput) { + return qq.isFile(maybeFileOrInput) || qq.isInput(maybeFileOrInput); + }; + qq.isInput = function(maybeInput, notFile) { + var evaluateType = function(type) { + var normalizedType = type.toLowerCase(); + if (notFile) { + return normalizedType !== "file"; + } + return normalizedType === "file"; + }; + if (window.HTMLInputElement) { + if (Object.prototype.toString.call(maybeInput) === "[object HTMLInputElement]") { + if (maybeInput.type && evaluateType(maybeInput.type)) { + return true; + } + } + } + if (maybeInput.tagName) { + if (maybeInput.tagName.toLowerCase() === "input") { + if (maybeInput.type && evaluateType(maybeInput.type)) { + return true; + } + } + } + return false; + }; + qq.isBlob = function(maybeBlob) { + if (window.Blob && Object.prototype.toString.call(maybeBlob) === "[object Blob]") { + return true; + } + }; + qq.isXhrUploadSupported = function() { + var input = document.createElement("input"); + input.type = "file"; + return input.multiple !== undefined && typeof File !== "undefined" && typeof FormData !== "undefined" && typeof qq.createXhrInstance().upload !== "undefined"; + }; + qq.createXhrInstance = function() { + if (window.XMLHttpRequest) { + return new XMLHttpRequest(); + } + try { + return new ActiveXObject("MSXML2.XMLHTTP.3.0"); + } catch (error) { + qq.log("Neither XHR or ActiveX are supported!", "error"); + return null; + } + }; + qq.isFolderDropSupported = function(dataTransfer) { + return dataTransfer.items && dataTransfer.items.length > 0 && dataTransfer.items[0].webkitGetAsEntry; + }; + qq.isFileChunkingSupported = function() { + return !qq.androidStock() && qq.isXhrUploadSupported() && (File.prototype.slice !== undefined || File.prototype.webkitSlice !== undefined || File.prototype.mozSlice !== undefined); + }; + qq.sliceBlob = function(fileOrBlob, start, end) { + var slicer = fileOrBlob.slice || fileOrBlob.mozSlice || fileOrBlob.webkitSlice; + return slicer.call(fileOrBlob, start, end); + }; + qq.arrayBufferToHex = function(buffer) { + var bytesAsHex = "", bytes = new Uint8Array(buffer); + qq.each(bytes, function(idx, byt) { + var byteAsHexStr = byt.toString(16); + if (byteAsHexStr.length < 2) { + byteAsHexStr = "0" + byteAsHexStr; + } + bytesAsHex += byteAsHexStr; + }); + return bytesAsHex; + }; + qq.readBlobToHex = function(blob, startOffset, length) { + var initialBlob = qq.sliceBlob(blob, startOffset, startOffset + length), fileReader = new FileReader(), promise = new qq.Promise(); + fileReader.onload = function() { + promise.success(qq.arrayBufferToHex(fileReader.result)); + }; + fileReader.onerror = promise.failure; + fileReader.readAsArrayBuffer(initialBlob); + return promise; + }; + qq.extend = function(first, second, extendNested) { + qq.each(second, function(prop, val) { + if (extendNested && qq.isObject(val)) { + if (first[prop] === undefined) { + first[prop] = {}; + } + qq.extend(first[prop], val, true); + } else { + first[prop] = val; + } + }); + return first; + }; + qq.override = function(target, sourceFn) { + var super_ = {}, source = sourceFn(super_); + qq.each(source, function(srcPropName, srcPropVal) { + if (target[srcPropName] !== undefined) { + super_[srcPropName] = target[srcPropName]; + } + target[srcPropName] = srcPropVal; + }); + return target; + }; + qq.indexOf = function(arr, elt, from) { + if (arr.indexOf) { + return arr.indexOf(elt, from); + } + from = from || 0; + var len = arr.length; + if (from < 0) { + from += len; + } + for (;from < len; from += 1) { + if (arr.hasOwnProperty(from) && arr[from] === elt) { + return from; + } + } + return -1; + }; + qq.getUniqueId = function() { + return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) { + var r = Math.random() * 16 | 0, v = c == "x" ? r : r & 3 | 8; + return v.toString(16); + }); + }; + qq.ie = function() { + return navigator.userAgent.indexOf("MSIE") !== -1 || navigator.userAgent.indexOf("Trident") !== -1; + }; + qq.ie7 = function() { + return navigator.userAgent.indexOf("MSIE 7") !== -1; + }; + qq.ie8 = function() { + return navigator.userAgent.indexOf("MSIE 8") !== -1; + }; + qq.ie10 = function() { + return navigator.userAgent.indexOf("MSIE 10") !== -1; + }; + qq.ie11 = function() { + return qq.ie() && navigator.userAgent.indexOf("rv:11") !== -1; + }; + qq.edge = function() { + return navigator.userAgent.indexOf("Edge") >= 0; + }; + qq.safari = function() { + return navigator.vendor !== undefined && navigator.vendor.indexOf("Apple") !== -1; + }; + qq.chrome = function() { + return navigator.vendor !== undefined && navigator.vendor.indexOf("Google") !== -1; + }; + qq.opera = function() { + return navigator.vendor !== undefined && navigator.vendor.indexOf("Opera") !== -1; + }; + qq.firefox = function() { + return !qq.edge() && !qq.ie11() && navigator.userAgent.indexOf("Mozilla") !== -1 && navigator.vendor !== undefined && navigator.vendor === ""; + }; + qq.windows = function() { + return navigator.platform === "Win32"; + }; + qq.android = function() { + return navigator.userAgent.toLowerCase().indexOf("android") !== -1; + }; + qq.androidStock = function() { + return qq.android() && navigator.userAgent.toLowerCase().indexOf("chrome") < 0; + }; + qq.ios6 = function() { + return qq.ios() && navigator.userAgent.indexOf(" OS 6_") !== -1; + }; + qq.ios7 = function() { + return qq.ios() && navigator.userAgent.indexOf(" OS 7_") !== -1; + }; + qq.ios8 = function() { + return qq.ios() && navigator.userAgent.indexOf(" OS 8_") !== -1; + }; + qq.ios800 = function() { + return qq.ios() && navigator.userAgent.indexOf(" OS 8_0 ") !== -1; + }; + qq.ios = function() { + return navigator.userAgent.indexOf("iPad") !== -1 || navigator.userAgent.indexOf("iPod") !== -1 || navigator.userAgent.indexOf("iPhone") !== -1; + }; + qq.iosChrome = function() { + return qq.ios() && navigator.userAgent.indexOf("CriOS") !== -1; + }; + qq.iosSafari = function() { + return qq.ios() && !qq.iosChrome() && navigator.userAgent.indexOf("Safari") !== -1; + }; + qq.iosSafariWebView = function() { + return qq.ios() && !qq.iosChrome() && !qq.iosSafari(); + }; + qq.preventDefault = function(e) { + if (e.preventDefault) { + e.preventDefault(); + } else { + e.returnValue = false; + } + }; + qq.toElement = function() { + var div = document.createElement("div"); + return function(html) { + div.innerHTML = html; + var element = div.firstChild; + div.removeChild(element); + return element; + }; + }(); + qq.each = function(iterableItem, callback) { + var keyOrIndex, retVal; + if (iterableItem) { + if (window.Storage && iterableItem.constructor === window.Storage) { + for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) { + retVal = callback(iterableItem.key(keyOrIndex), iterableItem.getItem(iterableItem.key(keyOrIndex))); + if (retVal === false) { + break; + } + } + } else if (qq.isArray(iterableItem) || qq.isItemList(iterableItem) || qq.isNodeList(iterableItem)) { + for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) { + retVal = callback(keyOrIndex, iterableItem[keyOrIndex]); + if (retVal === false) { + break; + } + } + } else if (qq.isString(iterableItem)) { + for (keyOrIndex = 0; keyOrIndex < iterableItem.length; keyOrIndex++) { + retVal = callback(keyOrIndex, iterableItem.charAt(keyOrIndex)); + if (retVal === false) { + break; + } + } + } else { + for (keyOrIndex in iterableItem) { + if (Object.prototype.hasOwnProperty.call(iterableItem, keyOrIndex)) { + retVal = callback(keyOrIndex, iterableItem[keyOrIndex]); + if (retVal === false) { + break; + } + } + } + } + } + }; + qq.bind = function(oldFunc, context) { + if (qq.isFunction(oldFunc)) { + var args = Array.prototype.slice.call(arguments, 2); + return function() { + var newArgs = qq.extend([], args); + if (arguments.length) { + newArgs = newArgs.concat(Array.prototype.slice.call(arguments)); + } + return oldFunc.apply(context, newArgs); + }; + } + throw new Error("first parameter must be a function!"); + }; + qq.obj2url = function(obj, temp, prefixDone) { + var uristrings = [], prefix = "&", add = function(nextObj, i) { + var nextTemp = temp ? /\[\]$/.test(temp) ? temp : temp + "[" + i + "]" : i; + if (nextTemp !== "undefined" && i !== "undefined") { + uristrings.push(typeof nextObj === "object" ? qq.obj2url(nextObj, nextTemp, true) : Object.prototype.toString.call(nextObj) === "[object Function]" ? encodeURIComponent(nextTemp) + "=" + encodeURIComponent(nextObj()) : encodeURIComponent(nextTemp) + "=" + encodeURIComponent(nextObj)); + } + }; + if (!prefixDone && temp) { + prefix = /\?/.test(temp) ? /\?$/.test(temp) ? "" : "&" : "?"; + uristrings.push(temp); + uristrings.push(qq.obj2url(obj)); + } else if (Object.prototype.toString.call(obj) === "[object Array]" && typeof obj !== "undefined") { + qq.each(obj, function(idx, val) { + add(val, idx); + }); + } else if (typeof obj !== "undefined" && obj !== null && typeof obj === "object") { + qq.each(obj, function(prop, val) { + add(val, prop); + }); + } else { + uristrings.push(encodeURIComponent(temp) + "=" + encodeURIComponent(obj)); + } + if (temp) { + return uristrings.join(prefix); + } else { + return uristrings.join(prefix).replace(/^&/, "").replace(/%20/g, "+"); + } + }; + qq.obj2FormData = function(obj, formData, arrayKeyName) { + if (!formData) { + formData = new FormData(); + } + qq.each(obj, function(key, val) { + key = arrayKeyName ? arrayKeyName + "[" + key + "]" : key; + if (qq.isObject(val)) { + qq.obj2FormData(val, formData, key); + } else if (qq.isFunction(val)) { + formData.append(key, val()); + } else { + formData.append(key, val); + } + }); + return formData; + }; + qq.obj2Inputs = function(obj, form) { + var input; + if (!form) { + form = document.createElement("form"); + } + qq.obj2FormData(obj, { + append: function(key, val) { + input = document.createElement("input"); + input.setAttribute("name", key); + input.setAttribute("value", val); + form.appendChild(input); + } + }); + return form; + }; + qq.parseJson = function(json) { + if (window.JSON && qq.isFunction(JSON.parse)) { + return JSON.parse(json); + } else { + return eval("(" + json + ")"); + } + }; + qq.getExtension = function(filename) { + var extIdx = filename.lastIndexOf(".") + 1; + if (extIdx > 0) { + return filename.substr(extIdx, filename.length - extIdx); + } + }; + qq.getFilename = function(blobOrFileInput) { + if (qq.isInput(blobOrFileInput)) { + return blobOrFileInput.value.replace(/.*(\/|\\)/, ""); + } else if (qq.isFile(blobOrFileInput)) { + if (blobOrFileInput.fileName !== null && blobOrFileInput.fileName !== undefined) { + return blobOrFileInput.fileName; + } + } + return blobOrFileInput.name; + }; + qq.DisposeSupport = function() { + var disposers = []; + return { + dispose: function() { + var disposer; + do { + disposer = disposers.shift(); + if (disposer) { + disposer(); + } + } while (disposer); + }, + attach: function() { + var args = arguments; + this.addDisposer(qq(args[0]).attach.apply(this, Array.prototype.slice.call(arguments, 1))); + }, + addDisposer: function(disposeFunction) { + disposers.push(disposeFunction); + } + }; + }; + })(); + (function() { + "use strict"; + if (typeof define === "function" && define.amd) { + define(function() { + return qq; + }); + } else if (typeof module !== "undefined" && module.exports) { + module.exports = qq; + } else { + global.qq = qq; + } + })(); + (function() { + "use strict"; + qq.Error = function(message) { + this.message = "[Fine Uploader " + qq.version + "] " + message; + }; + qq.Error.prototype = new Error(); + })(); + qq.version = "5.12.0"; + qq.supportedFeatures = function() { + "use strict"; + var supportsUploading, supportsUploadingBlobs, supportsFileDrop, supportsAjaxFileUploading, supportsFolderDrop, supportsChunking, supportsResume, supportsUploadViaPaste, supportsUploadCors, supportsDeleteFileXdr, supportsDeleteFileCorsXhr, supportsDeleteFileCors, supportsFolderSelection, supportsImagePreviews, supportsUploadProgress; + function testSupportsFileInputElement() { + var supported = true, tempInput; + try { + tempInput = document.createElement("input"); + tempInput.type = "file"; + qq(tempInput).hide(); + if (tempInput.disabled) { + supported = false; + } + } catch (ex) { + supported = false; + } + return supported; + } + function isChrome21OrHigher() { + return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/) !== undefined; + } + function isChrome14OrHigher() { + return (qq.chrome() || qq.opera()) && navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/) !== undefined; + } + function isCrossOriginXhrSupported() { + if (window.XMLHttpRequest) { + var xhr = qq.createXhrInstance(); + return xhr.withCredentials !== undefined; + } + return false; + } + function isXdrSupported() { + return window.XDomainRequest !== undefined; + } + function isCrossOriginAjaxSupported() { + if (isCrossOriginXhrSupported()) { + return true; + } + return isXdrSupported(); + } + function isFolderSelectionSupported() { + return document.createElement("input").webkitdirectory !== undefined; + } + function isLocalStorageSupported() { + try { + return !!window.localStorage && qq.isFunction(window.localStorage.setItem); + } catch (error) { + return false; + } + } + function isDragAndDropSupported() { + var span = document.createElement("span"); + return ("draggable" in span || "ondragstart" in span && "ondrop" in span) && !qq.android() && !qq.ios(); + } + supportsUploading = testSupportsFileInputElement(); + supportsAjaxFileUploading = supportsUploading && qq.isXhrUploadSupported(); + supportsUploadingBlobs = supportsAjaxFileUploading && !qq.androidStock(); + supportsFileDrop = supportsAjaxFileUploading && isDragAndDropSupported(); + supportsFolderDrop = supportsFileDrop && isChrome21OrHigher(); + supportsChunking = supportsAjaxFileUploading && qq.isFileChunkingSupported(); + supportsResume = supportsAjaxFileUploading && supportsChunking && isLocalStorageSupported(); + supportsUploadViaPaste = supportsAjaxFileUploading && isChrome14OrHigher(); + supportsUploadCors = supportsUploading && (window.postMessage !== undefined || supportsAjaxFileUploading); + supportsDeleteFileCorsXhr = isCrossOriginXhrSupported(); + supportsDeleteFileXdr = isXdrSupported(); + supportsDeleteFileCors = isCrossOriginAjaxSupported(); + supportsFolderSelection = isFolderSelectionSupported(); + supportsImagePreviews = supportsAjaxFileUploading && window.FileReader !== undefined; + supportsUploadProgress = function() { + if (supportsAjaxFileUploading) { + return !qq.androidStock() && !qq.iosChrome(); + } + return false; + }(); + return { + ajaxUploading: supportsAjaxFileUploading, + blobUploading: supportsUploadingBlobs, + canDetermineSize: supportsAjaxFileUploading, + chunking: supportsChunking, + deleteFileCors: supportsDeleteFileCors, + deleteFileCorsXdr: supportsDeleteFileXdr, + deleteFileCorsXhr: supportsDeleteFileCorsXhr, + dialogElement: !!window.HTMLDialogElement, + fileDrop: supportsFileDrop, + folderDrop: supportsFolderDrop, + folderSelection: supportsFolderSelection, + imagePreviews: supportsImagePreviews, + imageValidation: supportsImagePreviews, + itemSizeValidation: supportsAjaxFileUploading, + pause: supportsChunking, + progressBar: supportsUploadProgress, + resume: supportsResume, + scaling: supportsImagePreviews && supportsUploadingBlobs, + tiffPreviews: qq.safari(), + unlimitedScaledImageSize: !qq.ios(), + uploading: supportsUploading, + uploadCors: supportsUploadCors, + uploadCustomHeaders: supportsAjaxFileUploading, + uploadNonMultipart: supportsAjaxFileUploading, + uploadViaPaste: supportsUploadViaPaste + }; + }(); + qq.isGenericPromise = function(maybePromise) { + "use strict"; + return !!(maybePromise && maybePromise.then && qq.isFunction(maybePromise.then)); + }; + qq.Promise = function() { + "use strict"; + var successArgs, failureArgs, successCallbacks = [], failureCallbacks = [], doneCallbacks = [], state = 0; + qq.extend(this, { + then: function(onSuccess, onFailure) { + if (state === 0) { + if (onSuccess) { + successCallbacks.push(onSuccess); + } + if (onFailure) { + failureCallbacks.push(onFailure); + } + } else if (state === -1) { + onFailure && onFailure.apply(null, failureArgs); + } else if (onSuccess) { + onSuccess.apply(null, successArgs); + } + return this; + }, + done: function(callback) { + if (state === 0) { + doneCallbacks.push(callback); + } else { + callback.apply(null, failureArgs === undefined ? successArgs : failureArgs); + } + return this; + }, + success: function() { + state = 1; + successArgs = arguments; + if (successCallbacks.length) { + qq.each(successCallbacks, function(idx, callback) { + callback.apply(null, successArgs); + }); + } + if (doneCallbacks.length) { + qq.each(doneCallbacks, function(idx, callback) { + callback.apply(null, successArgs); + }); + } + return this; + }, + failure: function() { + state = -1; + failureArgs = arguments; + if (failureCallbacks.length) { + qq.each(failureCallbacks, function(idx, callback) { + callback.apply(null, failureArgs); + }); + } + if (doneCallbacks.length) { + qq.each(doneCallbacks, function(idx, callback) { + callback.apply(null, failureArgs); + }); + } + return this; + } + }); + }; + qq.BlobProxy = function(referenceBlob, onCreate) { + "use strict"; + qq.extend(this, { + referenceBlob: referenceBlob, + create: function() { + return onCreate(referenceBlob); + } + }); + }; + qq.UploadButton = function(o) { + "use strict"; + var self = this, disposeSupport = new qq.DisposeSupport(), options = { + acceptFiles: null, + element: null, + focusClass: "qq-upload-button-focus", + folders: false, + hoverClass: "qq-upload-button-hover", + ios8BrowserCrashWorkaround: false, + multiple: false, + name: "qqfile", + onChange: function(input) {}, + title: null + }, input, buttonId; + qq.extend(options, o); + buttonId = qq.getUniqueId(); + function createInput() { + var input = document.createElement("input"); + input.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME, buttonId); + input.setAttribute("title", options.title); + self.setMultiple(options.multiple, input); + if (options.folders && qq.supportedFeatures.folderSelection) { + input.setAttribute("webkitdirectory", ""); + } + if (options.acceptFiles) { + input.setAttribute("accept", options.acceptFiles); + } + input.setAttribute("type", "file"); + input.setAttribute("name", options.name); + qq(input).css({ + position: "absolute", + right: 0, + top: 0, + fontFamily: "Arial", + fontSize: qq.ie() && !qq.ie8() ? "3500px" : "118px", + margin: 0, + padding: 0, + cursor: "pointer", + opacity: 0 + }); + !qq.ie7() && qq(input).css({ + height: "100%" + }); + options.element.appendChild(input); + disposeSupport.attach(input, "change", function() { + options.onChange(input); + }); + disposeSupport.attach(input, "mouseover", function() { + qq(options.element).addClass(options.hoverClass); + }); + disposeSupport.attach(input, "mouseout", function() { + qq(options.element).removeClass(options.hoverClass); + }); + disposeSupport.attach(input, "focus", function() { + qq(options.element).addClass(options.focusClass); + }); + disposeSupport.attach(input, "blur", function() { + qq(options.element).removeClass(options.focusClass); + }); + return input; + } + qq(options.element).css({ + position: "relative", + overflow: "hidden", + direction: "ltr" + }); + qq.extend(this, { + getInput: function() { + return input; + }, + getButtonId: function() { + return buttonId; + }, + setMultiple: function(isMultiple, optInput) { + var input = optInput || this.getInput(); + if (options.ios8BrowserCrashWorkaround && qq.ios8() && (qq.iosChrome() || qq.iosSafariWebView())) { + input.setAttribute("multiple", ""); + } else { + if (isMultiple) { + input.setAttribute("multiple", ""); + } else { + input.removeAttribute("multiple"); + } + } + }, + setAcceptFiles: function(acceptFiles) { + if (acceptFiles !== options.acceptFiles) { + input.setAttribute("accept", acceptFiles); + } + }, + reset: function() { + if (input.parentNode) { + qq(input).remove(); + } + qq(options.element).removeClass(options.focusClass); + input = null; + input = createInput(); + } + }); + input = createInput(); + }; + qq.UploadButton.BUTTON_ID_ATTR_NAME = "qq-button-id"; + qq.UploadData = function(uploaderProxy) { + "use strict"; + var data = [], byUuid = {}, byStatus = {}, byProxyGroupId = {}, byBatchId = {}; + function getDataByIds(idOrIds) { + if (qq.isArray(idOrIds)) { + var entries = []; + qq.each(idOrIds, function(idx, id) { + entries.push(data[id]); + }); + return entries; + } + return data[idOrIds]; + } + function getDataByUuids(uuids) { + if (qq.isArray(uuids)) { + var entries = []; + qq.each(uuids, function(idx, uuid) { + entries.push(data[byUuid[uuid]]); + }); + return entries; + } + return data[byUuid[uuids]]; + } + function getDataByStatus(status) { + var statusResults = [], statuses = [].concat(status); + qq.each(statuses, function(index, statusEnum) { + var statusResultIndexes = byStatus[statusEnum]; + if (statusResultIndexes !== undefined) { + qq.each(statusResultIndexes, function(i, dataIndex) { + statusResults.push(data[dataIndex]); + }); + } + }); + return statusResults; + } + qq.extend(this, { + addFile: function(spec) { + var status = spec.status || qq.status.SUBMITTING, id = data.push({ + name: spec.name, + originalName: spec.name, + uuid: spec.uuid, + size: spec.size == null ? -1 : spec.size, + status: status + }) - 1; + if (spec.batchId) { + data[id].batchId = spec.batchId; + if (byBatchId[spec.batchId] === undefined) { + byBatchId[spec.batchId] = []; + } + byBatchId[spec.batchId].push(id); + } + if (spec.proxyGroupId) { + data[id].proxyGroupId = spec.proxyGroupId; + if (byProxyGroupId[spec.proxyGroupId] === undefined) { + byProxyGroupId[spec.proxyGroupId] = []; + } + byProxyGroupId[spec.proxyGroupId].push(id); + } + data[id].id = id; + byUuid[spec.uuid] = id; + if (byStatus[status] === undefined) { + byStatus[status] = []; + } + byStatus[status].push(id); + uploaderProxy.onStatusChange(id, null, status); + return id; + }, + retrieve: function(optionalFilter) { + if (qq.isObject(optionalFilter) && data.length) { + if (optionalFilter.id !== undefined) { + return getDataByIds(optionalFilter.id); + } else if (optionalFilter.uuid !== undefined) { + return getDataByUuids(optionalFilter.uuid); + } else if (optionalFilter.status) { + return getDataByStatus(optionalFilter.status); + } + } else { + return qq.extend([], data, true); + } + }, + reset: function() { + data = []; + byUuid = {}; + byStatus = {}; + byBatchId = {}; + }, + setStatus: function(id, newStatus) { + var oldStatus = data[id].status, byStatusOldStatusIndex = qq.indexOf(byStatus[oldStatus], id); + byStatus[oldStatus].splice(byStatusOldStatusIndex, 1); + data[id].status = newStatus; + if (byStatus[newStatus] === undefined) { + byStatus[newStatus] = []; + } + byStatus[newStatus].push(id); + uploaderProxy.onStatusChange(id, oldStatus, newStatus); + }, + uuidChanged: function(id, newUuid) { + var oldUuid = data[id].uuid; + data[id].uuid = newUuid; + byUuid[newUuid] = id; + delete byUuid[oldUuid]; + }, + updateName: function(id, newName) { + data[id].name = newName; + }, + updateSize: function(id, newSize) { + data[id].size = newSize; + }, + setParentId: function(targetId, parentId) { + data[targetId].parentId = parentId; + }, + getIdsInProxyGroup: function(id) { + var proxyGroupId = data[id].proxyGroupId; + if (proxyGroupId) { + return byProxyGroupId[proxyGroupId]; + } + return []; + }, + getIdsInBatch: function(id) { + var batchId = data[id].batchId; + return byBatchId[batchId]; + } + }); + }; + qq.status = { + SUBMITTING: "submitting", + SUBMITTED: "submitted", + REJECTED: "rejected", + QUEUED: "queued", + CANCELED: "canceled", + PAUSED: "paused", + UPLOADING: "uploading", + UPLOAD_RETRYING: "retrying upload", + UPLOAD_SUCCESSFUL: "upload successful", + UPLOAD_FAILED: "upload failed", + DELETE_FAILED: "delete failed", + DELETING: "deleting", + DELETED: "deleted" + }; + (function() { + "use strict"; + qq.basePublicApi = { + addBlobs: function(blobDataOrArray, params, endpoint) { + this.addFiles(blobDataOrArray, params, endpoint); + }, + addInitialFiles: function(cannedFileList) { + var self = this; + qq.each(cannedFileList, function(index, cannedFile) { + self._addCannedFile(cannedFile); + }); + }, + addFiles: function(data, params, endpoint) { + this._maybeHandleIos8SafariWorkaround(); + var batchId = this._storedIds.length === 0 ? qq.getUniqueId() : this._currentBatchId, processBlob = qq.bind(function(blob) { + this._handleNewFile({ + blob: blob, + name: this._options.blobs.defaultName + }, batchId, verifiedFiles); + }, this), processBlobData = qq.bind(function(blobData) { + this._handleNewFile(blobData, batchId, verifiedFiles); + }, this), processCanvas = qq.bind(function(canvas) { + var blob = qq.canvasToBlob(canvas); + this._handleNewFile({ + blob: blob, + name: this._options.blobs.defaultName + ".png" + }, batchId, verifiedFiles); + }, this), processCanvasData = qq.bind(function(canvasData) { + var normalizedQuality = canvasData.quality && canvasData.quality / 100, blob = qq.canvasToBlob(canvasData.canvas, canvasData.type, normalizedQuality); + this._handleNewFile({ + blob: blob, + name: canvasData.name + }, batchId, verifiedFiles); + }, this), processFileOrInput = qq.bind(function(fileOrInput) { + if (qq.isInput(fileOrInput) && qq.supportedFeatures.ajaxUploading) { + var files = Array.prototype.slice.call(fileOrInput.files), self = this; + qq.each(files, function(idx, file) { + self._handleNewFile(file, batchId, verifiedFiles); + }); + } else { + this._handleNewFile(fileOrInput, batchId, verifiedFiles); + } + }, this), normalizeData = function() { + if (qq.isFileList(data)) { + data = Array.prototype.slice.call(data); + } + data = [].concat(data); + }, self = this, verifiedFiles = []; + this._currentBatchId = batchId; + if (data) { + normalizeData(); + qq.each(data, function(idx, fileContainer) { + if (qq.isFileOrInput(fileContainer)) { + processFileOrInput(fileContainer); + } else if (qq.isBlob(fileContainer)) { + processBlob(fileContainer); + } else if (qq.isObject(fileContainer)) { + if (fileContainer.blob && fileContainer.name) { + processBlobData(fileContainer); + } else if (fileContainer.canvas && fileContainer.name) { + processCanvasData(fileContainer); + } + } else if (fileContainer.tagName && fileContainer.tagName.toLowerCase() === "canvas") { + processCanvas(fileContainer); + } else { + self.log(fileContainer + " is not a valid file container! Ignoring!", "warn"); + } + }); + this.log("Received " + verifiedFiles.length + " files."); + this._prepareItemsForUpload(verifiedFiles, params, endpoint); + } + }, + cancel: function(id) { + this._handler.cancel(id); + }, + cancelAll: function() { + var storedIdsCopy = [], self = this; + qq.extend(storedIdsCopy, this._storedIds); + qq.each(storedIdsCopy, function(idx, storedFileId) { + self.cancel(storedFileId); + }); + this._handler.cancelAll(); + }, + clearStoredFiles: function() { + this._storedIds = []; + }, + continueUpload: function(id) { + var uploadData = this._uploadData.retrieve({ + id: id + }); + if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) { + return false; + } + if (uploadData.status === qq.status.PAUSED) { + this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.", id, this.getName(id))); + this._uploadFile(id); + return true; + } else { + this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.", id, this.getName(id)), "error"); + } + return false; + }, + deleteFile: function(id) { + return this._onSubmitDelete(id); + }, + doesExist: function(fileOrBlobId) { + return this._handler.isValid(fileOrBlobId); + }, + drawThumbnail: function(fileId, imgOrCanvas, maxSize, fromServer, customResizeFunction) { + var promiseToReturn = new qq.Promise(), fileOrUrl, options; + if (this._imageGenerator) { + fileOrUrl = this._thumbnailUrls[fileId]; + options = { + customResizeFunction: customResizeFunction, + maxSize: maxSize > 0 ? maxSize : null, + scale: maxSize > 0 + }; + if (!fromServer && qq.supportedFeatures.imagePreviews) { + fileOrUrl = this.getFile(fileId); + } + if (fileOrUrl == null) { + promiseToReturn.failure({ + container: imgOrCanvas, + error: "File or URL not found." + }); + } else { + this._imageGenerator.generate(fileOrUrl, imgOrCanvas, options).then(function success(modifiedContainer) { + promiseToReturn.success(modifiedContainer); + }, function failure(container, reason) { + promiseToReturn.failure({ + container: container, + error: reason || "Problem generating thumbnail" + }); + }); + } + } else { + promiseToReturn.failure({ + container: imgOrCanvas, + error: "Missing image generator module" + }); + } + return promiseToReturn; + }, + getButton: function(fileId) { + return this._getButton(this._buttonIdsForFileIds[fileId]); + }, + getEndpoint: function(fileId) { + return this._endpointStore.get(fileId); + }, + getFile: function(fileOrBlobId) { + return this._handler.getFile(fileOrBlobId) || null; + }, + getInProgress: function() { + return this._uploadData.retrieve({ + status: [ qq.status.UPLOADING, qq.status.UPLOAD_RETRYING, qq.status.QUEUED ] + }).length; + }, + getName: function(id) { + return this._uploadData.retrieve({ + id: id + }).name; + }, + getParentId: function(id) { + var uploadDataEntry = this.getUploads({ + id: id + }), parentId = null; + if (uploadDataEntry) { + if (uploadDataEntry.parentId !== undefined) { + parentId = uploadDataEntry.parentId; + } + } + return parentId; + }, + getResumableFilesData: function() { + return this._handler.getResumableFilesData(); + }, + getSize: function(id) { + return this._uploadData.retrieve({ + id: id + }).size; + }, + getNetUploads: function() { + return this._netUploaded; + }, + getRemainingAllowedItems: function() { + var allowedItems = this._currentItemLimit; + if (allowedItems > 0) { + return allowedItems - this._netUploadedOrQueued; + } + return null; + }, + getUploads: function(optionalFilter) { + return this._uploadData.retrieve(optionalFilter); + }, + getUuid: function(id) { + return this._uploadData.retrieve({ + id: id + }).uuid; + }, + log: function(str, level) { + if (this._options.debug && (!level || level === "info")) { + qq.log("[Fine Uploader " + qq.version + "] " + str); + } else if (level && level !== "info") { + qq.log("[Fine Uploader " + qq.version + "] " + str, level); + } + }, + pauseUpload: function(id) { + var uploadData = this._uploadData.retrieve({ + id: id + }); + if (!qq.supportedFeatures.pause || !this._options.chunking.enabled) { + return false; + } + if (qq.indexOf([ qq.status.UPLOADING, qq.status.UPLOAD_RETRYING ], uploadData.status) >= 0) { + if (this._handler.pause(id)) { + this._uploadData.setStatus(id, qq.status.PAUSED); + return true; + } else { + this.log(qq.format("Unable to pause file ID {} ({}).", id, this.getName(id)), "error"); + } + } else { + this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.", id, this.getName(id)), "error"); + } + return false; + }, + reset: function() { + this.log("Resetting uploader..."); + this._handler.reset(); + this._storedIds = []; + this._autoRetries = []; + this._retryTimeouts = []; + this._preventRetries = []; + this._thumbnailUrls = []; + qq.each(this._buttons, function(idx, button) { + button.reset(); + }); + this._paramsStore.reset(); + this._endpointStore.reset(); + this._netUploadedOrQueued = 0; + this._netUploaded = 0; + this._uploadData.reset(); + this._buttonIdsForFileIds = []; + this._pasteHandler && this._pasteHandler.reset(); + this._options.session.refreshOnReset && this._refreshSessionData(); + this._succeededSinceLastAllComplete = []; + this._failedSinceLastAllComplete = []; + this._totalProgress && this._totalProgress.reset(); + }, + retry: function(id) { + return this._manualRetry(id); + }, + scaleImage: function(id, specs) { + var self = this; + return qq.Scaler.prototype.scaleImage(id, specs, { + log: qq.bind(self.log, self), + getFile: qq.bind(self.getFile, self), + uploadData: self._uploadData + }); + }, + setCustomHeaders: function(headers, id) { + this._customHeadersStore.set(headers, id); + }, + setDeleteFileCustomHeaders: function(headers, id) { + this._deleteFileCustomHeadersStore.set(headers, id); + }, + setDeleteFileEndpoint: function(endpoint, id) { + this._deleteFileEndpointStore.set(endpoint, id); + }, + setDeleteFileParams: function(params, id) { + this._deleteFileParamsStore.set(params, id); + }, + setEndpoint: function(endpoint, id) { + this._endpointStore.set(endpoint, id); + }, + setForm: function(elementOrId) { + this._updateFormSupportAndParams(elementOrId); + }, + setItemLimit: function(newItemLimit) { + this._currentItemLimit = newItemLimit; + }, + setName: function(id, newName) { + this._uploadData.updateName(id, newName); + }, + setParams: function(params, id) { + this._paramsStore.set(params, id); + }, + setUuid: function(id, newUuid) { + return this._uploadData.uuidChanged(id, newUuid); + }, + uploadStoredFiles: function() { + if (this._storedIds.length === 0) { + this._itemError("noFilesError"); + } else { + this._uploadStoredFiles(); + } + } + }; + qq.basePrivateApi = { + _addCannedFile: function(sessionData) { + var id = this._uploadData.addFile({ + uuid: sessionData.uuid, + name: sessionData.name, + size: sessionData.size, + status: qq.status.UPLOAD_SUCCESSFUL + }); + sessionData.deleteFileEndpoint && this.setDeleteFileEndpoint(sessionData.deleteFileEndpoint, id); + sessionData.deleteFileParams && this.setDeleteFileParams(sessionData.deleteFileParams, id); + if (sessionData.thumbnailUrl) { + this._thumbnailUrls[id] = sessionData.thumbnailUrl; + } + this._netUploaded++; + this._netUploadedOrQueued++; + return id; + }, + _annotateWithButtonId: function(file, associatedInput) { + if (qq.isFile(file)) { + file.qqButtonId = this._getButtonId(associatedInput); + } + }, + _batchError: function(message) { + this._options.callbacks.onError(null, null, message, undefined); + }, + _createDeleteHandler: function() { + var self = this; + return new qq.DeleteFileAjaxRequester({ + method: this._options.deleteFile.method.toUpperCase(), + maxConnections: this._options.maxConnections, + uuidParamName: this._options.request.uuidName, + customHeaders: this._deleteFileCustomHeadersStore, + paramsStore: this._deleteFileParamsStore, + endpointStore: this._deleteFileEndpointStore, + cors: this._options.cors, + log: qq.bind(self.log, self), + onDelete: function(id) { + self._onDelete(id); + self._options.callbacks.onDelete(id); + }, + onDeleteComplete: function(id, xhrOrXdr, isError) { + self._onDeleteComplete(id, xhrOrXdr, isError); + self._options.callbacks.onDeleteComplete(id, xhrOrXdr, isError); + } + }); + }, + _createPasteHandler: function() { + var self = this; + return new qq.PasteSupport({ + targetElement: this._options.paste.targetElement, + callbacks: { + log: qq.bind(self.log, self), + pasteReceived: function(blob) { + self._handleCheckedCallback({ + name: "onPasteReceived", + callback: qq.bind(self._options.callbacks.onPasteReceived, self, blob), + onSuccess: qq.bind(self._handlePasteSuccess, self, blob), + identifier: "pasted image" + }); + } + } + }); + }, + _createStore: function(initialValue, _readOnlyValues_) { + var store = {}, catchall = initialValue, perIdReadOnlyValues = {}, readOnlyValues = _readOnlyValues_, copy = function(orig) { + if (qq.isObject(orig)) { + return qq.extend({}, orig); + } + return orig; + }, getReadOnlyValues = function() { + if (qq.isFunction(readOnlyValues)) { + return readOnlyValues(); + } + return readOnlyValues; + }, includeReadOnlyValues = function(id, existing) { + if (readOnlyValues && qq.isObject(existing)) { + qq.extend(existing, getReadOnlyValues()); + } + if (perIdReadOnlyValues[id]) { + qq.extend(existing, perIdReadOnlyValues[id]); + } + }; + return { + set: function(val, id) { + if (id == null) { + store = {}; + catchall = copy(val); + } else { + store[id] = copy(val); + } + }, + get: function(id) { + var values; + if (id != null && store[id]) { + values = store[id]; + } else { + values = copy(catchall); + } + includeReadOnlyValues(id, values); + return copy(values); + }, + addReadOnly: function(id, values) { + if (qq.isObject(store)) { + if (id === null) { + if (qq.isFunction(values)) { + readOnlyValues = values; + } else { + readOnlyValues = readOnlyValues || {}; + qq.extend(readOnlyValues, values); + } + } else { + perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {}; + qq.extend(perIdReadOnlyValues[id], values); + } + } + }, + remove: function(fileId) { + return delete store[fileId]; + }, + reset: function() { + store = {}; + perIdReadOnlyValues = {}; + catchall = initialValue; + } + }; + }, + _createUploadDataTracker: function() { + var self = this; + return new qq.UploadData({ + getName: function(id) { + return self.getName(id); + }, + getUuid: function(id) { + return self.getUuid(id); + }, + getSize: function(id) { + return self.getSize(id); + }, + onStatusChange: function(id, oldStatus, newStatus) { + self._onUploadStatusChange(id, oldStatus, newStatus); + self._options.callbacks.onStatusChange(id, oldStatus, newStatus); + self._maybeAllComplete(id, newStatus); + if (self._totalProgress) { + setTimeout(function() { + self._totalProgress.onStatusChange(id, oldStatus, newStatus); + }, 0); + } + } + }); + }, + _createUploadButton: function(spec) { + var self = this, acceptFiles = spec.accept || this._options.validation.acceptFiles, allowedExtensions = spec.allowedExtensions || this._options.validation.allowedExtensions, button; + function allowMultiple() { + if (qq.supportedFeatures.ajaxUploading) { + if (self._options.workarounds.iosEmptyVideos && qq.ios() && !qq.ios6() && self._isAllowedExtension(allowedExtensions, ".mov")) { + return false; + } + if (spec.multiple === undefined) { + return self._options.multiple; + } + return spec.multiple; + } + return false; + } + button = new qq.UploadButton({ + acceptFiles: acceptFiles, + element: spec.element, + focusClass: this._options.classes.buttonFocus, + folders: spec.folders, + hoverClass: this._options.classes.buttonHover, + ios8BrowserCrashWorkaround: this._options.workarounds.ios8BrowserCrash, + multiple: allowMultiple(), + name: this._options.request.inputName, + onChange: function(input) { + self._onInputChange(input); + }, + title: spec.title == null ? this._options.text.fileInputTitle : spec.title + }); + this._disposeSupport.addDisposer(function() { + button.dispose(); + }); + self._buttons.push(button); + return button; + }, + _createUploadHandler: function(additionalOptions, namespace) { + var self = this, lastOnProgress = {}, options = { + debug: this._options.debug, + maxConnections: this._options.maxConnections, + cors: this._options.cors, + paramsStore: this._paramsStore, + endpointStore: this._endpointStore, + chunking: this._options.chunking, + resume: this._options.resume, + blobs: this._options.blobs, + log: qq.bind(self.log, self), + preventRetryParam: this._options.retry.preventRetryResponseProperty, + onProgress: function(id, name, loaded, total) { + if (loaded < 0 || total < 0) { + return; + } + if (lastOnProgress[id]) { + if (lastOnProgress[id].loaded !== loaded || lastOnProgress[id].total !== total) { + self._onProgress(id, name, loaded, total); + self._options.callbacks.onProgress(id, name, loaded, total); + } + } else { + self._onProgress(id, name, loaded, total); + self._options.callbacks.onProgress(id, name, loaded, total); + } + lastOnProgress[id] = { + loaded: loaded, + total: total + }; + }, + onComplete: function(id, name, result, xhr) { + delete lastOnProgress[id]; + var status = self.getUploads({ + id: id + }).status, retVal; + if (status === qq.status.UPLOAD_SUCCESSFUL || status === qq.status.UPLOAD_FAILED) { + return; + } + retVal = self._onComplete(id, name, result, xhr); + if (retVal instanceof qq.Promise) { + retVal.done(function() { + self._options.callbacks.onComplete(id, name, result, xhr); + }); + } else { + self._options.callbacks.onComplete(id, name, result, xhr); + } + }, + onCancel: function(id, name, cancelFinalizationEffort) { + var promise = new qq.Promise(); + self._handleCheckedCallback({ + name: "onCancel", + callback: qq.bind(self._options.callbacks.onCancel, self, id, name), + onFailure: promise.failure, + onSuccess: function() { + cancelFinalizationEffort.then(function() { + self._onCancel(id, name); + }); + promise.success(); + }, + identifier: id + }); + return promise; + }, + onUploadPrep: qq.bind(this._onUploadPrep, this), + onUpload: function(id, name) { + self._onUpload(id, name); + self._options.callbacks.onUpload(id, name); + }, + onUploadChunk: function(id, name, chunkData) { + self._onUploadChunk(id, chunkData); + self._options.callbacks.onUploadChunk(id, name, chunkData); + }, + onUploadChunkSuccess: function(id, chunkData, result, xhr) { + self._options.callbacks.onUploadChunkSuccess.apply(self, arguments); + }, + onResume: function(id, name, chunkData) { + return self._options.callbacks.onResume(id, name, chunkData); + }, + onAutoRetry: function(id, name, responseJSON, xhr) { + return self._onAutoRetry.apply(self, arguments); + }, + onUuidChanged: function(id, newUuid) { + self.log("Server requested UUID change from '" + self.getUuid(id) + "' to '" + newUuid + "'"); + self.setUuid(id, newUuid); + }, + getName: qq.bind(self.getName, self), + getUuid: qq.bind(self.getUuid, self), + getSize: qq.bind(self.getSize, self), + setSize: qq.bind(self._setSize, self), + getDataByUuid: function(uuid) { + return self.getUploads({ + uuid: uuid + }); + }, + isQueued: function(id) { + var status = self.getUploads({ + id: id + }).status; + return status === qq.status.QUEUED || status === qq.status.SUBMITTED || status === qq.status.UPLOAD_RETRYING || status === qq.status.PAUSED; + }, + getIdsInProxyGroup: self._uploadData.getIdsInProxyGroup, + getIdsInBatch: self._uploadData.getIdsInBatch + }; + qq.each(this._options.request, function(prop, val) { + options[prop] = val; + }); + options.customHeaders = this._customHeadersStore; + if (additionalOptions) { + qq.each(additionalOptions, function(key, val) { + options[key] = val; + }); + } + return new qq.UploadHandlerController(options, namespace); + }, + _fileOrBlobRejected: function(id) { + this._netUploadedOrQueued--; + this._uploadData.setStatus(id, qq.status.REJECTED); + }, + _formatSize: function(bytes) { + if (bytes === 0) { + return bytes + this._options.text.sizeSymbols[0]; + } + var i = -1; + do { + bytes = bytes / 1e3; + i++; + } while (bytes > 999); + return Math.max(bytes, .1).toFixed(1) + this._options.text.sizeSymbols[i]; + }, + _generateExtraButtonSpecs: function() { + var self = this; + this._extraButtonSpecs = {}; + qq.each(this._options.extraButtons, function(idx, extraButtonOptionEntry) { + var multiple = extraButtonOptionEntry.multiple, validation = qq.extend({}, self._options.validation, true), extraButtonSpec = qq.extend({}, extraButtonOptionEntry); + if (multiple === undefined) { + multiple = self._options.multiple; + } + if (extraButtonSpec.validation) { + qq.extend(validation, extraButtonOptionEntry.validation, true); + } + qq.extend(extraButtonSpec, { + multiple: multiple, + validation: validation + }, true); + self._initExtraButton(extraButtonSpec); + }); + }, + _getButton: function(buttonId) { + var extraButtonsSpec = this._extraButtonSpecs[buttonId]; + if (extraButtonsSpec) { + return extraButtonsSpec.element; + } else if (buttonId === this._defaultButtonId) { + return this._options.button; + } + }, + _getButtonId: function(buttonOrFileInputOrFile) { + var inputs, fileInput, fileBlobOrInput = buttonOrFileInputOrFile; + if (fileBlobOrInput instanceof qq.BlobProxy) { + fileBlobOrInput = fileBlobOrInput.referenceBlob; + } + if (fileBlobOrInput && !qq.isBlob(fileBlobOrInput)) { + if (qq.isFile(fileBlobOrInput)) { + return fileBlobOrInput.qqButtonId; + } else if (fileBlobOrInput.tagName.toLowerCase() === "input" && fileBlobOrInput.type.toLowerCase() === "file") { + return fileBlobOrInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME); + } + inputs = fileBlobOrInput.getElementsByTagName("input"); + qq.each(inputs, function(idx, input) { + if (input.getAttribute("type") === "file") { + fileInput = input; + return false; + } + }); + if (fileInput) { + return fileInput.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME); + } + } + }, + _getNotFinished: function() { + return this._uploadData.retrieve({ + status: [ qq.status.UPLOADING, qq.status.UPLOAD_RETRYING, qq.status.QUEUED, qq.status.SUBMITTING, qq.status.SUBMITTED, qq.status.PAUSED ] + }).length; + }, + _getValidationBase: function(buttonId) { + var extraButtonSpec = this._extraButtonSpecs[buttonId]; + return extraButtonSpec ? extraButtonSpec.validation : this._options.validation; + }, + _getValidationDescriptor: function(fileWrapper) { + if (fileWrapper.file instanceof qq.BlobProxy) { + return { + name: qq.getFilename(fileWrapper.file.referenceBlob), + size: fileWrapper.file.referenceBlob.size + }; + } + return { + name: this.getUploads({ + id: fileWrapper.id + }).name, + size: this.getUploads({ + id: fileWrapper.id + }).size + }; + }, + _getValidationDescriptors: function(fileWrappers) { + var self = this, fileDescriptors = []; + qq.each(fileWrappers, function(idx, fileWrapper) { + fileDescriptors.push(self._getValidationDescriptor(fileWrapper)); + }); + return fileDescriptors; + }, + _handleCameraAccess: function() { + if (this._options.camera.ios && qq.ios()) { + var acceptIosCamera = "image/*;capture=camera", button = this._options.camera.button, buttonId = button ? this._getButtonId(button) : this._defaultButtonId, optionRoot = this._options; + if (buttonId && buttonId !== this._defaultButtonId) { + optionRoot = this._extraButtonSpecs[buttonId]; + } + optionRoot.multiple = false; + if (optionRoot.validation.acceptFiles === null) { + optionRoot.validation.acceptFiles = acceptIosCamera; + } else { + optionRoot.validation.acceptFiles += "," + acceptIosCamera; + } + qq.each(this._buttons, function(idx, button) { + if (button.getButtonId() === buttonId) { + button.setMultiple(optionRoot.multiple); + button.setAcceptFiles(optionRoot.acceptFiles); + return false; + } + }); + } + }, + _handleCheckedCallback: function(details) { + var self = this, callbackRetVal = details.callback(); + if (qq.isGenericPromise(callbackRetVal)) { + this.log(details.name + " - waiting for " + details.name + " promise to be fulfilled for " + details.identifier); + return callbackRetVal.then(function(successParam) { + self.log(details.name + " promise success for " + details.identifier); + details.onSuccess(successParam); + }, function() { + if (details.onFailure) { + self.log(details.name + " promise failure for " + details.identifier); + details.onFailure(); + } else { + self.log(details.name + " promise failure for " + details.identifier); + } + }); + } + if (callbackRetVal !== false) { + details.onSuccess(callbackRetVal); + } else { + if (details.onFailure) { + this.log(details.name + " - return value was 'false' for " + details.identifier + ". Invoking failure callback."); + details.onFailure(); + } else { + this.log(details.name + " - return value was 'false' for " + details.identifier + ". Will not proceed."); + } + } + return callbackRetVal; + }, + _handleNewFile: function(file, batchId, newFileWrapperList) { + var self = this, uuid = qq.getUniqueId(), size = -1, name = qq.getFilename(file), actualFile = file.blob || file, handler = this._customNewFileHandler ? this._customNewFileHandler : qq.bind(self._handleNewFileGeneric, self); + if (!qq.isInput(actualFile) && actualFile.size >= 0) { + size = actualFile.size; + } + handler(actualFile, name, uuid, size, newFileWrapperList, batchId, this._options.request.uuidName, { + uploadData: self._uploadData, + paramsStore: self._paramsStore, + addFileToHandler: function(id, file) { + self._handler.add(id, file); + self._netUploadedOrQueued++; + self._trackButton(id); + } + }); + }, + _handleNewFileGeneric: function(file, name, uuid, size, fileList, batchId) { + var id = this._uploadData.addFile({ + uuid: uuid, + name: name, + size: size, + batchId: batchId + }); + this._handler.add(id, file); + this._trackButton(id); + this._netUploadedOrQueued++; + fileList.push({ + id: id, + file: file + }); + }, + _handlePasteSuccess: function(blob, extSuppliedName) { + var extension = blob.type.split("/")[1], name = extSuppliedName; + if (name == null) { + name = this._options.paste.defaultName; + } + name += "." + extension; + this.addFiles({ + name: name, + blob: blob + }); + }, + _initExtraButton: function(spec) { + var button = this._createUploadButton({ + accept: spec.validation.acceptFiles, + allowedExtensions: spec.validation.allowedExtensions, + element: spec.element, + folders: spec.folders, + multiple: spec.multiple, + title: spec.fileInputTitle + }); + this._extraButtonSpecs[button.getButtonId()] = spec; + }, + _initFormSupportAndParams: function() { + this._formSupport = qq.FormSupport && new qq.FormSupport(this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)); + if (this._formSupport && this._formSupport.attachedToForm) { + this._paramsStore = this._createStore(this._options.request.params, this._formSupport.getFormInputsAsObject); + this._options.autoUpload = this._formSupport.newAutoUpload; + if (this._formSupport.newEndpoint) { + this._options.request.endpoint = this._formSupport.newEndpoint; + } + } else { + this._paramsStore = this._createStore(this._options.request.params); + } + }, + _isDeletePossible: function() { + if (!qq.DeleteFileAjaxRequester || !this._options.deleteFile.enabled) { + return false; + } + if (this._options.cors.expected) { + if (qq.supportedFeatures.deleteFileCorsXhr) { + return true; + } + if (qq.supportedFeatures.deleteFileCorsXdr && this._options.cors.allowXdr) { + return true; + } + return false; + } + return true; + }, + _isAllowedExtension: function(allowed, fileName) { + var valid = false; + if (!allowed.length) { + return true; + } + qq.each(allowed, function(idx, allowedExt) { + if (qq.isString(allowedExt)) { + var extRegex = new RegExp("\\." + allowedExt + "$", "i"); + if (fileName.match(extRegex) != null) { + valid = true; + return false; + } + } + }); + return valid; + }, + _itemError: function(code, maybeNameOrNames, item) { + var message = this._options.messages[code], allowedExtensions = [], names = [].concat(maybeNameOrNames), name = names[0], buttonId = this._getButtonId(item), validationBase = this._getValidationBase(buttonId), extensionsForMessage, placeholderMatch; + function r(name, replacement) { + message = message.replace(name, replacement); + } + qq.each(validationBase.allowedExtensions, function(idx, allowedExtension) { + if (qq.isString(allowedExtension)) { + allowedExtensions.push(allowedExtension); + } + }); + extensionsForMessage = allowedExtensions.join(", ").toLowerCase(); + r("{file}", this._options.formatFileName(name)); + r("{extensions}", extensionsForMessage); + r("{sizeLimit}", this._formatSize(validationBase.sizeLimit)); + r("{minSizeLimit}", this._formatSize(validationBase.minSizeLimit)); + placeholderMatch = message.match(/(\{\w+\})/g); + if (placeholderMatch !== null) { + qq.each(placeholderMatch, function(idx, placeholder) { + r(placeholder, names[idx]); + }); + } + this._options.callbacks.onError(null, name, message, undefined); + return message; + }, + _manualRetry: function(id, callback) { + if (this._onBeforeManualRetry(id)) { + this._netUploadedOrQueued++; + this._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING); + if (callback) { + callback(id); + } else { + this._handler.retry(id); + } + return true; + } + }, + _maybeAllComplete: function(id, status) { + var self = this, notFinished = this._getNotFinished(); + if (status === qq.status.UPLOAD_SUCCESSFUL) { + this._succeededSinceLastAllComplete.push(id); + } else if (status === qq.status.UPLOAD_FAILED) { + this._failedSinceLastAllComplete.push(id); + } + if (notFinished === 0 && (this._succeededSinceLastAllComplete.length || this._failedSinceLastAllComplete.length)) { + setTimeout(function() { + self._onAllComplete(self._succeededSinceLastAllComplete, self._failedSinceLastAllComplete); + }, 0); + } + }, + _maybeHandleIos8SafariWorkaround: function() { + var self = this; + if (this._options.workarounds.ios8SafariUploads && qq.ios800() && qq.iosSafari()) { + setTimeout(function() { + window.alert(self._options.messages.unsupportedBrowserIos8Safari); + }, 0); + throw new qq.Error(this._options.messages.unsupportedBrowserIos8Safari); + } + }, + _maybeParseAndSendUploadError: function(id, name, response, xhr) { + if (!response.success) { + if (xhr && xhr.status !== 200 && !response.error) { + this._options.callbacks.onError(id, name, "XHR returned response code " + xhr.status, xhr); + } else { + var errorReason = response.error ? response.error : this._options.text.defaultResponseError; + this._options.callbacks.onError(id, name, errorReason, xhr); + } + } + }, + _maybeProcessNextItemAfterOnValidateCallback: function(validItem, items, index, params, endpoint) { + var self = this; + if (items.length > index) { + if (validItem || !this._options.validation.stopOnFirstInvalidFile) { + setTimeout(function() { + var validationDescriptor = self._getValidationDescriptor(items[index]), buttonId = self._getButtonId(items[index].file), button = self._getButton(buttonId); + self._handleCheckedCallback({ + name: "onValidate", + callback: qq.bind(self._options.callbacks.onValidate, self, validationDescriptor, button), + onSuccess: qq.bind(self._onValidateCallbackSuccess, self, items, index, params, endpoint), + onFailure: qq.bind(self._onValidateCallbackFailure, self, items, index, params, endpoint), + identifier: "Item '" + validationDescriptor.name + "', size: " + validationDescriptor.size + }); + }, 0); + } else if (!validItem) { + for (;index < items.length; index++) { + self._fileOrBlobRejected(items[index].id); + } + } + } + }, + _onAllComplete: function(successful, failed) { + this._totalProgress && this._totalProgress.onAllComplete(successful, failed, this._preventRetries); + this._options.callbacks.onAllComplete(qq.extend([], successful), qq.extend([], failed)); + this._succeededSinceLastAllComplete = []; + this._failedSinceLastAllComplete = []; + }, + _onAutoRetry: function(id, name, responseJSON, xhr, callback) { + var self = this; + self._preventRetries[id] = responseJSON[self._options.retry.preventRetryResponseProperty]; + if (self._shouldAutoRetry(id, name, responseJSON)) { + var retryWaitPeriod = self._options.retry.autoAttemptDelay * 1e3; + self._maybeParseAndSendUploadError.apply(self, arguments); + self._options.callbacks.onAutoRetry(id, name, self._autoRetries[id]); + self._onBeforeAutoRetry(id, name); + self._uploadData.setStatus(id, qq.status.UPLOAD_RETRYING); + self._retryTimeouts[id] = setTimeout(function() { + self.log("Starting retry for " + name + "..."); + if (callback) { + callback(id); + } else { + self._handler.retry(id); + } + }, retryWaitPeriod); + return true; + } + }, + _onBeforeAutoRetry: function(id, name) { + this.log("Waiting " + this._options.retry.autoAttemptDelay + " seconds before retrying " + name + "..."); + }, + _onBeforeManualRetry: function(id) { + var itemLimit = this._currentItemLimit, fileName; + if (this._preventRetries[id]) { + this.log("Retries are forbidden for id " + id, "warn"); + return false; + } else if (this._handler.isValid(id)) { + fileName = this.getName(id); + if (this._options.callbacks.onManualRetry(id, fileName) === false) { + return false; + } + if (itemLimit > 0 && this._netUploadedOrQueued + 1 > itemLimit) { + this._itemError("retryFailTooManyItems"); + return false; + } + this.log("Retrying upload for '" + fileName + "' (id: " + id + ")..."); + return true; + } else { + this.log("'" + id + "' is not a valid file ID", "error"); + return false; + } + }, + _onCancel: function(id, name) { + this._netUploadedOrQueued--; + clearTimeout(this._retryTimeouts[id]); + var storedItemIndex = qq.indexOf(this._storedIds, id); + if (!this._options.autoUpload && storedItemIndex >= 0) { + this._storedIds.splice(storedItemIndex, 1); + } + this._uploadData.setStatus(id, qq.status.CANCELED); + }, + _onComplete: function(id, name, result, xhr) { + if (!result.success) { + this._netUploadedOrQueued--; + this._uploadData.setStatus(id, qq.status.UPLOAD_FAILED); + if (result[this._options.retry.preventRetryResponseProperty] === true) { + this._preventRetries[id] = true; + } + } else { + if (result.thumbnailUrl) { + this._thumbnailUrls[id] = result.thumbnailUrl; + } + this._netUploaded++; + this._uploadData.setStatus(id, qq.status.UPLOAD_SUCCESSFUL); + } + this._maybeParseAndSendUploadError(id, name, result, xhr); + return result.success ? true : false; + }, + _onDelete: function(id) { + this._uploadData.setStatus(id, qq.status.DELETING); + }, + _onDeleteComplete: function(id, xhrOrXdr, isError) { + var name = this.getName(id); + if (isError) { + this._uploadData.setStatus(id, qq.status.DELETE_FAILED); + this.log("Delete request for '" + name + "' has failed.", "error"); + if (xhrOrXdr.withCredentials === undefined) { + this._options.callbacks.onError(id, name, "Delete request failed", xhrOrXdr); + } else { + this._options.callbacks.onError(id, name, "Delete request failed with response code " + xhrOrXdr.status, xhrOrXdr); + } + } else { + this._netUploadedOrQueued--; + this._netUploaded--; + this._handler.expunge(id); + this._uploadData.setStatus(id, qq.status.DELETED); + this.log("Delete request for '" + name + "' has succeeded."); + } + }, + _onInputChange: function(input) { + var fileIndex; + if (qq.supportedFeatures.ajaxUploading) { + for (fileIndex = 0; fileIndex < input.files.length; fileIndex++) { + this._annotateWithButtonId(input.files[fileIndex], input); + } + this.addFiles(input.files); + } else if (input.value.length > 0) { + this.addFiles(input); + } + qq.each(this._buttons, function(idx, button) { + button.reset(); + }); + }, + _onProgress: function(id, name, loaded, total) { + this._totalProgress && this._totalProgress.onIndividualProgress(id, loaded, total); + }, + _onSubmit: function(id, name) {}, + _onSubmitCallbackSuccess: function(id, name) { + this._onSubmit.apply(this, arguments); + this._uploadData.setStatus(id, qq.status.SUBMITTED); + this._onSubmitted.apply(this, arguments); + if (this._options.autoUpload) { + this._options.callbacks.onSubmitted.apply(this, arguments); + this._uploadFile(id); + } else { + this._storeForLater(id); + this._options.callbacks.onSubmitted.apply(this, arguments); + } + }, + _onSubmitDelete: function(id, onSuccessCallback, additionalMandatedParams) { + var uuid = this.getUuid(id), adjustedOnSuccessCallback; + if (onSuccessCallback) { + adjustedOnSuccessCallback = qq.bind(onSuccessCallback, this, id, uuid, additionalMandatedParams); + } + if (this._isDeletePossible()) { + this._handleCheckedCallback({ + name: "onSubmitDelete", + callback: qq.bind(this._options.callbacks.onSubmitDelete, this, id), + onSuccess: adjustedOnSuccessCallback || qq.bind(this._deleteHandler.sendDelete, this, id, uuid, additionalMandatedParams), + identifier: id + }); + return true; + } else { + this.log("Delete request ignored for ID " + id + ", delete feature is disabled or request not possible " + "due to CORS on a user agent that does not support pre-flighting.", "warn"); + return false; + } + }, + _onSubmitted: function(id) {}, + _onTotalProgress: function(loaded, total) { + this._options.callbacks.onTotalProgress(loaded, total); + }, + _onUploadPrep: function(id) {}, + _onUpload: function(id, name) { + this._uploadData.setStatus(id, qq.status.UPLOADING); + }, + _onUploadChunk: function(id, chunkData) {}, + _onUploadStatusChange: function(id, oldStatus, newStatus) { + if (newStatus === qq.status.PAUSED) { + clearTimeout(this._retryTimeouts[id]); + } + }, + _onValidateBatchCallbackFailure: function(fileWrappers) { + var self = this; + qq.each(fileWrappers, function(idx, fileWrapper) { + self._fileOrBlobRejected(fileWrapper.id); + }); + }, + _onValidateBatchCallbackSuccess: function(validationDescriptors, items, params, endpoint, button) { + var errorMessage, itemLimit = this._currentItemLimit, proposedNetFilesUploadedOrQueued = this._netUploadedOrQueued; + if (itemLimit === 0 || proposedNetFilesUploadedOrQueued <= itemLimit) { + if (items.length > 0) { + this._handleCheckedCallback({ + name: "onValidate", + callback: qq.bind(this._options.callbacks.onValidate, this, validationDescriptors[0], button), + onSuccess: qq.bind(this._onValidateCallbackSuccess, this, items, 0, params, endpoint), + onFailure: qq.bind(this._onValidateCallbackFailure, this, items, 0, params, endpoint), + identifier: "Item '" + items[0].file.name + "', size: " + items[0].file.size + }); + } else { + this._itemError("noFilesError"); + } + } else { + this._onValidateBatchCallbackFailure(items); + errorMessage = this._options.messages.tooManyItemsError.replace(/\{netItems\}/g, proposedNetFilesUploadedOrQueued).replace(/\{itemLimit\}/g, itemLimit); + this._batchError(errorMessage); + } + }, + _onValidateCallbackFailure: function(items, index, params, endpoint) { + var nextIndex = index + 1; + this._fileOrBlobRejected(items[index].id, items[index].file.name); + this._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint); + }, + _onValidateCallbackSuccess: function(items, index, params, endpoint) { + var self = this, nextIndex = index + 1, validationDescriptor = this._getValidationDescriptor(items[index]); + this._validateFileOrBlobData(items[index], validationDescriptor).then(function() { + self._upload(items[index].id, params, endpoint); + self._maybeProcessNextItemAfterOnValidateCallback(true, items, nextIndex, params, endpoint); + }, function() { + self._maybeProcessNextItemAfterOnValidateCallback(false, items, nextIndex, params, endpoint); + }); + }, + _prepareItemsForUpload: function(items, params, endpoint) { + if (items.length === 0) { + this._itemError("noFilesError"); + return; + } + var validationDescriptors = this._getValidationDescriptors(items), buttonId = this._getButtonId(items[0].file), button = this._getButton(buttonId); + this._handleCheckedCallback({ + name: "onValidateBatch", + callback: qq.bind(this._options.callbacks.onValidateBatch, this, validationDescriptors, button), + onSuccess: qq.bind(this._onValidateBatchCallbackSuccess, this, validationDescriptors, items, params, endpoint, button), + onFailure: qq.bind(this._onValidateBatchCallbackFailure, this, items), + identifier: "batch validation" + }); + }, + _preventLeaveInProgress: function() { + var self = this; + this._disposeSupport.attach(window, "beforeunload", function(e) { + if (self.getInProgress()) { + e = e || window.event; + e.returnValue = self._options.messages.onLeave; + return self._options.messages.onLeave; + } + }); + }, + _refreshSessionData: function() { + var self = this, options = this._options.session; + if (qq.Session && this._options.session.endpoint != null) { + if (!this._session) { + qq.extend(options, { + cors: this._options.cors + }); + options.log = qq.bind(this.log, this); + options.addFileRecord = qq.bind(this._addCannedFile, this); + this._session = new qq.Session(options); + } + setTimeout(function() { + self._session.refresh().then(function(response, xhrOrXdr) { + self._sessionRequestComplete(); + self._options.callbacks.onSessionRequestComplete(response, true, xhrOrXdr); + }, function(response, xhrOrXdr) { + self._options.callbacks.onSessionRequestComplete(response, false, xhrOrXdr); + }); + }, 0); + } + }, + _sessionRequestComplete: function() {}, + _setSize: function(id, newSize) { + this._uploadData.updateSize(id, newSize); + this._totalProgress && this._totalProgress.onNewSize(id); + }, + _shouldAutoRetry: function(id, name, responseJSON) { + var uploadData = this._uploadData.retrieve({ + id: id + }); + if (!this._preventRetries[id] && this._options.retry.enableAuto && uploadData.status !== qq.status.PAUSED) { + if (this._autoRetries[id] === undefined) { + this._autoRetries[id] = 0; + } + if (this._autoRetries[id] < this._options.retry.maxAutoAttempts) { + this._autoRetries[id] += 1; + return true; + } + } + return false; + }, + _storeForLater: function(id) { + this._storedIds.push(id); + }, + _trackButton: function(id) { + var buttonId; + if (qq.supportedFeatures.ajaxUploading) { + buttonId = this._handler.getFile(id).qqButtonId; + } else { + buttonId = this._getButtonId(this._handler.getInput(id)); + } + if (buttonId) { + this._buttonIdsForFileIds[id] = buttonId; + } + }, + _updateFormSupportAndParams: function(formElementOrId) { + this._options.form.element = formElementOrId; + this._formSupport = qq.FormSupport && new qq.FormSupport(this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)); + if (this._formSupport && this._formSupport.attachedToForm) { + this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject); + this._options.autoUpload = this._formSupport.newAutoUpload; + if (this._formSupport.newEndpoint) { + this.setEndpoint(this._formSupport.newEndpoint); + } + } + }, + _upload: function(id, params, endpoint) { + var name = this.getName(id); + if (params) { + this.setParams(params, id); + } + if (endpoint) { + this.setEndpoint(endpoint, id); + } + this._handleCheckedCallback({ + name: "onSubmit", + callback: qq.bind(this._options.callbacks.onSubmit, this, id, name), + onSuccess: qq.bind(this._onSubmitCallbackSuccess, this, id, name), + onFailure: qq.bind(this._fileOrBlobRejected, this, id, name), + identifier: id + }); + }, + _uploadFile: function(id) { + if (!this._handler.upload(id)) { + this._uploadData.setStatus(id, qq.status.QUEUED); + } + }, + _uploadStoredFiles: function() { + var idToUpload, stillSubmitting, self = this; + while (this._storedIds.length) { + idToUpload = this._storedIds.shift(); + this._uploadFile(idToUpload); + } + stillSubmitting = this.getUploads({ + status: qq.status.SUBMITTING + }).length; + if (stillSubmitting) { + qq.log("Still waiting for " + stillSubmitting + " files to clear submit queue. Will re-parse stored IDs array shortly."); + setTimeout(function() { + self._uploadStoredFiles(); + }, 1e3); + } + }, + _validateFileOrBlobData: function(fileWrapper, validationDescriptor) { + var self = this, file = function() { + if (fileWrapper.file instanceof qq.BlobProxy) { + return fileWrapper.file.referenceBlob; + } + return fileWrapper.file; + }(), name = validationDescriptor.name, size = validationDescriptor.size, buttonId = this._getButtonId(fileWrapper.file), validationBase = this._getValidationBase(buttonId), validityChecker = new qq.Promise(); + validityChecker.then(function() {}, function() { + self._fileOrBlobRejected(fileWrapper.id, name); + }); + if (qq.isFileOrInput(file) && !this._isAllowedExtension(validationBase.allowedExtensions, name)) { + this._itemError("typeError", name, file); + return validityChecker.failure(); + } + if (!this._options.validation.allowEmpty && size === 0) { + this._itemError("emptyError", name, file); + return validityChecker.failure(); + } + if (size > 0 && validationBase.sizeLimit && size > validationBase.sizeLimit) { + this._itemError("sizeError", name, file); + return validityChecker.failure(); + } + if (size > 0 && size < validationBase.minSizeLimit) { + this._itemError("minSizeError", name, file); + return validityChecker.failure(); + } + if (qq.ImageValidation && qq.supportedFeatures.imagePreviews && qq.isFile(file)) { + new qq.ImageValidation(file, qq.bind(self.log, self)).validate(validationBase.image).then(validityChecker.success, function(errorCode) { + self._itemError(errorCode + "ImageError", name, file); + validityChecker.failure(); + }); + } else { + validityChecker.success(); + } + return validityChecker; + }, + _wrapCallbacks: function() { + var self, safeCallback, prop; + self = this; + safeCallback = function(name, callback, args) { + var errorMsg; + try { + return callback.apply(self, args); + } catch (exception) { + errorMsg = exception.message || exception.toString(); + self.log("Caught exception in '" + name + "' callback - " + errorMsg, "error"); + } + }; + for (prop in this._options.callbacks) { + (function() { + var callbackName, callbackFunc; + callbackName = prop; + callbackFunc = self._options.callbacks[callbackName]; + self._options.callbacks[callbackName] = function() { + return safeCallback(callbackName, callbackFunc, arguments); + }; + })(); + } + } + }; + })(); + (function() { + "use strict"; + qq.FineUploaderBasic = function(o) { + var self = this; + this._options = { + debug: false, + button: null, + multiple: true, + maxConnections: 3, + disableCancelForFormUploads: false, + autoUpload: true, + request: { + customHeaders: {}, + endpoint: "/server/upload", + filenameParam: "qqfilename", + forceMultipart: true, + inputName: "qqfile", + method: "POST", + params: {}, + paramsInBody: true, + totalFileSizeName: "qqtotalfilesize", + uuidName: "qquuid" + }, + validation: { + allowedExtensions: [], + sizeLimit: 0, + minSizeLimit: 0, + itemLimit: 0, + stopOnFirstInvalidFile: true, + acceptFiles: null, + image: { + maxHeight: 0, + maxWidth: 0, + minHeight: 0, + minWidth: 0 + }, + allowEmpty: false + }, + callbacks: { + onSubmit: function(id, name) {}, + onSubmitted: function(id, name) {}, + onComplete: function(id, name, responseJSON, maybeXhr) {}, + onAllComplete: function(successful, failed) {}, + onCancel: function(id, name) {}, + onUpload: function(id, name) {}, + onUploadChunk: function(id, name, chunkData) {}, + onUploadChunkSuccess: function(id, chunkData, responseJSON, xhr) {}, + onResume: function(id, fileName, chunkData) {}, + onProgress: function(id, name, loaded, total) {}, + onTotalProgress: function(loaded, total) {}, + onError: function(id, name, reason, maybeXhrOrXdr) {}, + onAutoRetry: function(id, name, attemptNumber) {}, + onManualRetry: function(id, name) {}, + onValidateBatch: function(fileOrBlobData) {}, + onValidate: function(fileOrBlobData) {}, + onSubmitDelete: function(id) {}, + onDelete: function(id) {}, + onDeleteComplete: function(id, xhrOrXdr, isError) {}, + onPasteReceived: function(blob) {}, + onStatusChange: function(id, oldStatus, newStatus) {}, + onSessionRequestComplete: function(response, success, xhrOrXdr) {} + }, + messages: { + typeError: "{file} has an invalid extension. Valid extension(s): {extensions}.", + sizeError: "{file} is too large, maximum file size is {sizeLimit}.", + minSizeError: "{file} is too small, minimum file size is {minSizeLimit}.", + emptyError: "{file} is empty, please select files again without it.", + noFilesError: "No files to upload.", + tooManyItemsError: "Too many items ({netItems}) would be uploaded. Item limit is {itemLimit}.", + maxHeightImageError: "Image is too tall.", + maxWidthImageError: "Image is too wide.", + minHeightImageError: "Image is not tall enough.", + minWidthImageError: "Image is not wide enough.", + retryFailTooManyItems: "Retry failed - you have reached your file limit.", + onLeave: "The files are being uploaded, if you leave now the upload will be canceled.", + unsupportedBrowserIos8Safari: "Unrecoverable error - this browser does not permit file uploading of any kind due to serious bugs in iOS8 Safari. Please use iOS8 Chrome until Apple fixes these issues." + }, + retry: { + enableAuto: false, + maxAutoAttempts: 3, + autoAttemptDelay: 5, + preventRetryResponseProperty: "preventRetry" + }, + classes: { + buttonHover: "qq-upload-button-hover", + buttonFocus: "qq-upload-button-focus" + }, + chunking: { + enabled: false, + concurrent: { + enabled: false + }, + mandatory: false, + paramNames: { + partIndex: "qqpartindex", + partByteOffset: "qqpartbyteoffset", + chunkSize: "qqchunksize", + totalFileSize: "qqtotalfilesize", + totalParts: "qqtotalparts" + }, + partSize: 2e6, + success: { + endpoint: null + } + }, + resume: { + enabled: false, + recordsExpireIn: 7, + paramNames: { + resuming: "qqresume" + } + }, + formatFileName: function(fileOrBlobName) { + return fileOrBlobName; + }, + text: { + defaultResponseError: "Upload failure reason unknown", + fileInputTitle: "file input", + sizeSymbols: [ "kB", "MB", "GB", "TB", "PB", "EB" ] + }, + deleteFile: { + enabled: false, + method: "DELETE", + endpoint: "/server/upload", + customHeaders: {}, + params: {} + }, + cors: { + expected: false, + sendCredentials: false, + allowXdr: false + }, + blobs: { + defaultName: "misc_data" + }, + paste: { + targetElement: null, + defaultName: "pasted_image" + }, + camera: { + ios: false, + button: null + }, + extraButtons: [], + session: { + endpoint: null, + params: {}, + customHeaders: {}, + refreshOnReset: true + }, + form: { + element: "qq-form", + autoUpload: false, + interceptSubmit: true + }, + scaling: { + customResizer: null, + sendOriginal: true, + orient: true, + defaultType: null, + defaultQuality: 80, + failureText: "Failed to scale", + includeExif: false, + sizes: [] + }, + workarounds: { + iosEmptyVideos: true, + ios8SafariUploads: true, + ios8BrowserCrash: false + } + }; + qq.extend(this._options, o, true); + this._buttons = []; + this._extraButtonSpecs = {}; + this._buttonIdsForFileIds = []; + this._wrapCallbacks(); + this._disposeSupport = new qq.DisposeSupport(); + this._storedIds = []; + this._autoRetries = []; + this._retryTimeouts = []; + this._preventRetries = []; + this._thumbnailUrls = []; + this._netUploadedOrQueued = 0; + this._netUploaded = 0; + this._uploadData = this._createUploadDataTracker(); + this._initFormSupportAndParams(); + this._customHeadersStore = this._createStore(this._options.request.customHeaders); + this._deleteFileCustomHeadersStore = this._createStore(this._options.deleteFile.customHeaders); + this._deleteFileParamsStore = this._createStore(this._options.deleteFile.params); + this._endpointStore = this._createStore(this._options.request.endpoint); + this._deleteFileEndpointStore = this._createStore(this._options.deleteFile.endpoint); + this._handler = this._createUploadHandler(); + this._deleteHandler = qq.DeleteFileAjaxRequester && this._createDeleteHandler(); + if (this._options.button) { + this._defaultButtonId = this._createUploadButton({ + element: this._options.button, + title: this._options.text.fileInputTitle + }).getButtonId(); + } + this._generateExtraButtonSpecs(); + this._handleCameraAccess(); + if (this._options.paste.targetElement) { + if (qq.PasteSupport) { + this._pasteHandler = this._createPasteHandler(); + } else { + this.log("Paste support module not found", "error"); + } + } + this._preventLeaveInProgress(); + this._imageGenerator = qq.ImageGenerator && new qq.ImageGenerator(qq.bind(this.log, this)); + this._refreshSessionData(); + this._succeededSinceLastAllComplete = []; + this._failedSinceLastAllComplete = []; + this._scaler = qq.Scaler && new qq.Scaler(this._options.scaling, qq.bind(this.log, this)) || {}; + if (this._scaler.enabled) { + this._customNewFileHandler = qq.bind(this._scaler.handleNewFile, this._scaler); + } + if (qq.TotalProgress && qq.supportedFeatures.progressBar) { + this._totalProgress = new qq.TotalProgress(qq.bind(this._onTotalProgress, this), function(id) { + var entry = self._uploadData.retrieve({ + id: id + }); + return entry && entry.size || 0; + }); + } + this._currentItemLimit = this._options.validation.itemLimit; + }; + qq.FineUploaderBasic.prototype = qq.basePublicApi; + qq.extend(qq.FineUploaderBasic.prototype, qq.basePrivateApi); + })(); + qq.AjaxRequester = function(o) { + "use strict"; + var log, shouldParamsBeInQueryString, queue = [], requestData = {}, options = { + acceptHeader: null, + validMethods: [ "PATCH", "POST", "PUT" ], + method: "POST", + contentType: "application/x-www-form-urlencoded", + maxConnections: 3, + customHeaders: {}, + endpointStore: {}, + paramsStore: {}, + mandatedParams: {}, + allowXRequestedWithAndCacheControl: true, + successfulResponseCodes: { + DELETE: [ 200, 202, 204 ], + PATCH: [ 200, 201, 202, 203, 204 ], + POST: [ 200, 201, 202, 203, 204 ], + PUT: [ 200, 201, 202, 203, 204 ], + GET: [ 200 ] + }, + cors: { + expected: false, + sendCredentials: false + }, + log: function(str, level) {}, + onSend: function(id) {}, + onComplete: function(id, xhrOrXdr, isError) {}, + onProgress: null + }; + qq.extend(options, o); + log = options.log; + if (qq.indexOf(options.validMethods, options.method) < 0) { + throw new Error("'" + options.method + "' is not a supported method for this type of request!"); + } + function isSimpleMethod() { + return qq.indexOf([ "GET", "POST", "HEAD" ], options.method) >= 0; + } + function containsNonSimpleHeaders(headers) { + var containsNonSimple = false; + qq.each(containsNonSimple, function(idx, header) { + if (qq.indexOf([ "Accept", "Accept-Language", "Content-Language", "Content-Type" ], header) < 0) { + containsNonSimple = true; + return false; + } + }); + return containsNonSimple; + } + function isXdr(xhr) { + return options.cors.expected && xhr.withCredentials === undefined; + } + function getCorsAjaxTransport() { + var xhrOrXdr; + if (window.XMLHttpRequest || window.ActiveXObject) { + xhrOrXdr = qq.createXhrInstance(); + if (xhrOrXdr.withCredentials === undefined) { + xhrOrXdr = new XDomainRequest(); + xhrOrXdr.onload = function() {}; + xhrOrXdr.onerror = function() {}; + xhrOrXdr.ontimeout = function() {}; + xhrOrXdr.onprogress = function() {}; + } + } + return xhrOrXdr; + } + function getXhrOrXdr(id, suppliedXhr) { + var xhrOrXdr = requestData[id].xhr; + if (!xhrOrXdr) { + if (suppliedXhr) { + xhrOrXdr = suppliedXhr; + } else { + if (options.cors.expected) { + xhrOrXdr = getCorsAjaxTransport(); + } else { + xhrOrXdr = qq.createXhrInstance(); + } + } + requestData[id].xhr = xhrOrXdr; + } + return xhrOrXdr; + } + function dequeue(id) { + var i = qq.indexOf(queue, id), max = options.maxConnections, nextId; + delete requestData[id]; + queue.splice(i, 1); + if (queue.length >= max && i < max) { + nextId = queue[max - 1]; + sendRequest(nextId); + } + } + function onComplete(id, xdrError) { + var xhr = getXhrOrXdr(id), method = options.method, isError = xdrError === true; + dequeue(id); + if (isError) { + log(method + " request for " + id + " has failed", "error"); + } else if (!isXdr(xhr) && !isResponseSuccessful(xhr.status)) { + isError = true; + log(method + " request for " + id + " has failed - response code " + xhr.status, "error"); + } + options.onComplete(id, xhr, isError); + } + function getParams(id) { + var onDemandParams = requestData[id].additionalParams, mandatedParams = options.mandatedParams, params; + if (options.paramsStore.get) { + params = options.paramsStore.get(id); + } + if (onDemandParams) { + qq.each(onDemandParams, function(name, val) { + params = params || {}; + params[name] = val; + }); + } + if (mandatedParams) { + qq.each(mandatedParams, function(name, val) { + params = params || {}; + params[name] = val; + }); + } + return params; + } + function sendRequest(id, optXhr) { + var xhr = getXhrOrXdr(id, optXhr), method = options.method, params = getParams(id), payload = requestData[id].payload, url; + options.onSend(id); + url = createUrl(id, params, requestData[id].additionalQueryParams); + if (isXdr(xhr)) { + xhr.onload = getXdrLoadHandler(id); + xhr.onerror = getXdrErrorHandler(id); + } else { + xhr.onreadystatechange = getXhrReadyStateChangeHandler(id); + } + registerForUploadProgress(id); + xhr.open(method, url, true); + if (options.cors.expected && options.cors.sendCredentials && !isXdr(xhr)) { + xhr.withCredentials = true; + } + setHeaders(id); + log("Sending " + method + " request for " + id); + if (payload) { + xhr.send(payload); + } else if (shouldParamsBeInQueryString || !params) { + xhr.send(); + } else if (params && options.contentType && options.contentType.toLowerCase().indexOf("application/x-www-form-urlencoded") >= 0) { + xhr.send(qq.obj2url(params, "")); + } else if (params && options.contentType && options.contentType.toLowerCase().indexOf("application/json") >= 0) { + xhr.send(JSON.stringify(params)); + } else { + xhr.send(params); + } + return xhr; + } + function createUrl(id, params, additionalQueryParams) { + var endpoint = options.endpointStore.get(id), addToPath = requestData[id].addToPath; + if (addToPath != undefined) { + endpoint += "/" + addToPath; + } + if (shouldParamsBeInQueryString && params) { + endpoint = qq.obj2url(params, endpoint); + } + if (additionalQueryParams) { + endpoint = qq.obj2url(additionalQueryParams, endpoint); + } + return endpoint; + } + function getXhrReadyStateChangeHandler(id) { + return function() { + if (getXhrOrXdr(id).readyState === 4) { + onComplete(id); + } + }; + } + function registerForUploadProgress(id) { + var onProgress = options.onProgress; + if (onProgress) { + getXhrOrXdr(id).upload.onprogress = function(e) { + if (e.lengthComputable) { + onProgress(id, e.loaded, e.total); + } + }; + } + } + function getXdrLoadHandler(id) { + return function() { + onComplete(id); + }; + } + function getXdrErrorHandler(id) { + return function() { + onComplete(id, true); + }; + } + function setHeaders(id) { + var xhr = getXhrOrXdr(id), customHeaders = options.customHeaders, onDemandHeaders = requestData[id].additionalHeaders || {}, method = options.method, allHeaders = {}; + if (!isXdr(xhr)) { + options.acceptHeader && xhr.setRequestHeader("Accept", options.acceptHeader); + if (options.allowXRequestedWithAndCacheControl) { + if (!options.cors.expected || (!isSimpleMethod() || containsNonSimpleHeaders(customHeaders))) { + xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + xhr.setRequestHeader("Cache-Control", "no-cache"); + } + } + if (options.contentType && (method === "POST" || method === "PUT")) { + xhr.setRequestHeader("Content-Type", options.contentType); + } + qq.extend(allHeaders, qq.isFunction(customHeaders) ? customHeaders(id) : customHeaders); + qq.extend(allHeaders, onDemandHeaders); + qq.each(allHeaders, function(name, val) { + xhr.setRequestHeader(name, val); + }); + } + } + function isResponseSuccessful(responseCode) { + return qq.indexOf(options.successfulResponseCodes[options.method], responseCode) >= 0; + } + function prepareToSend(id, optXhr, addToPath, additionalParams, additionalQueryParams, additionalHeaders, payload) { + requestData[id] = { + addToPath: addToPath, + additionalParams: additionalParams, + additionalQueryParams: additionalQueryParams, + additionalHeaders: additionalHeaders, + payload: payload + }; + var len = queue.push(id); + if (len <= options.maxConnections) { + return sendRequest(id, optXhr); + } + } + shouldParamsBeInQueryString = options.method === "GET" || options.method === "DELETE"; + qq.extend(this, { + initTransport: function(id) { + var path, params, headers, payload, cacheBuster, additionalQueryParams; + return { + withPath: function(appendToPath) { + path = appendToPath; + return this; + }, + withParams: function(additionalParams) { + params = additionalParams; + return this; + }, + withQueryParams: function(_additionalQueryParams_) { + additionalQueryParams = _additionalQueryParams_; + return this; + }, + withHeaders: function(additionalHeaders) { + headers = additionalHeaders; + return this; + }, + withPayload: function(thePayload) { + payload = thePayload; + return this; + }, + withCacheBuster: function() { + cacheBuster = true; + return this; + }, + send: function(optXhr) { + if (cacheBuster && qq.indexOf([ "GET", "DELETE" ], options.method) >= 0) { + params.qqtimestamp = new Date().getTime(); + } + return prepareToSend(id, optXhr, path, params, additionalQueryParams, headers, payload); + } + }; + }, + canceled: function(id) { + dequeue(id); + } + }); + }; + qq.UploadHandler = function(spec) { + "use strict"; + var proxy = spec.proxy, fileState = {}, onCancel = proxy.onCancel, getName = proxy.getName; + qq.extend(this, { + add: function(id, fileItem) { + fileState[id] = fileItem; + fileState[id].temp = {}; + }, + cancel: function(id) { + var self = this, cancelFinalizationEffort = new qq.Promise(), onCancelRetVal = onCancel(id, getName(id), cancelFinalizationEffort); + onCancelRetVal.then(function() { + if (self.isValid(id)) { + fileState[id].canceled = true; + self.expunge(id); + } + cancelFinalizationEffort.success(); + }); + }, + expunge: function(id) { + delete fileState[id]; + }, + getThirdPartyFileId: function(id) { + return fileState[id].key; + }, + isValid: function(id) { + return fileState[id] !== undefined; + }, + reset: function() { + fileState = {}; + }, + _getFileState: function(id) { + return fileState[id]; + }, + _setThirdPartyFileId: function(id, thirdPartyFileId) { + fileState[id].key = thirdPartyFileId; + }, + _wasCanceled: function(id) { + return !!fileState[id].canceled; + } + }); + }; + qq.UploadHandlerController = function(o, namespace) { + "use strict"; + var controller = this, chunkingPossible = false, concurrentChunkingPossible = false, chunking, preventRetryResponse, log, handler, options = { + paramsStore: {}, + maxConnections: 3, + chunking: { + enabled: false, + multiple: { + enabled: false + } + }, + log: function(str, level) {}, + onProgress: function(id, fileName, loaded, total) {}, + onComplete: function(id, fileName, response, xhr) {}, + onCancel: function(id, fileName) {}, + onUploadPrep: function(id) {}, + onUpload: function(id, fileName) {}, + onUploadChunk: function(id, fileName, chunkData) {}, + onUploadChunkSuccess: function(id, chunkData, response, xhr) {}, + onAutoRetry: function(id, fileName, response, xhr) {}, + onResume: function(id, fileName, chunkData) {}, + onUuidChanged: function(id, newUuid) {}, + getName: function(id) {}, + setSize: function(id, newSize) {}, + isQueued: function(id) {}, + getIdsInProxyGroup: function(id) {}, + getIdsInBatch: function(id) {} + }, chunked = { + done: function(id, chunkIdx, response, xhr) { + var chunkData = handler._getChunkData(id, chunkIdx); + handler._getFileState(id).attemptingResume = false; + delete handler._getFileState(id).temp.chunkProgress[chunkIdx]; + handler._getFileState(id).loaded += chunkData.size; + options.onUploadChunkSuccess(id, handler._getChunkDataForCallback(chunkData), response, xhr); + }, + finalize: function(id) { + var size = options.getSize(id), name = options.getName(id); + log("All chunks have been uploaded for " + id + " - finalizing...."); + handler.finalizeChunks(id).then(function(response, xhr) { + log("Finalize successful for " + id); + var normaizedResponse = upload.normalizeResponse(response, true); + options.onProgress(id, name, size, size); + handler._maybeDeletePersistedChunkData(id); + upload.cleanup(id, normaizedResponse, xhr); + }, function(response, xhr) { + var normaizedResponse = upload.normalizeResponse(response, false); + log("Problem finalizing chunks for file ID " + id + " - " + normaizedResponse.error, "error"); + if (normaizedResponse.reset) { + chunked.reset(id); + } + if (!options.onAutoRetry(id, name, normaizedResponse, xhr)) { + upload.cleanup(id, normaizedResponse, xhr); + } + }); + }, + handleFailure: function(chunkIdx, id, response, xhr) { + var name = options.getName(id); + log("Chunked upload request failed for " + id + ", chunk " + chunkIdx); + handler.clearCachedChunk(id, chunkIdx); + var responseToReport = upload.normalizeResponse(response, false), inProgressIdx; + if (responseToReport.reset) { + chunked.reset(id); + } else { + inProgressIdx = qq.indexOf(handler._getFileState(id).chunking.inProgress, chunkIdx); + if (inProgressIdx >= 0) { + handler._getFileState(id).chunking.inProgress.splice(inProgressIdx, 1); + handler._getFileState(id).chunking.remaining.unshift(chunkIdx); + } + } + if (!handler._getFileState(id).temp.ignoreFailure) { + if (concurrentChunkingPossible) { + handler._getFileState(id).temp.ignoreFailure = true; + log(qq.format("Going to attempt to abort these chunks: {}. These are currently in-progress: {}.", JSON.stringify(Object.keys(handler._getXhrs(id))), JSON.stringify(handler._getFileState(id).chunking.inProgress))); + qq.each(handler._getXhrs(id), function(ckid, ckXhr) { + log(qq.format("Attempting to abort file {}.{}. XHR readyState {}. ", id, ckid, ckXhr.readyState)); + ckXhr.abort(); + ckXhr._cancelled = true; + }); + handler.moveInProgressToRemaining(id); + connectionManager.free(id, true); + } + if (!options.onAutoRetry(id, name, responseToReport, xhr)) { + upload.cleanup(id, responseToReport, xhr); + } + } + }, + hasMoreParts: function(id) { + return !!handler._getFileState(id).chunking.remaining.length; + }, + nextPart: function(id) { + var nextIdx = handler._getFileState(id).chunking.remaining.shift(); + if (nextIdx >= handler._getTotalChunks(id)) { + nextIdx = null; + } + return nextIdx; + }, + reset: function(id) { + log("Server or callback has ordered chunking effort to be restarted on next attempt for item ID " + id, "error"); + handler._maybeDeletePersistedChunkData(id); + handler.reevaluateChunking(id); + handler._getFileState(id).loaded = 0; + }, + sendNext: function(id) { + var size = options.getSize(id), name = options.getName(id), chunkIdx = chunked.nextPart(id), chunkData = handler._getChunkData(id, chunkIdx), resuming = handler._getFileState(id).attemptingResume, inProgressChunks = handler._getFileState(id).chunking.inProgress || []; + if (handler._getFileState(id).loaded == null) { + handler._getFileState(id).loaded = 0; + } + if (resuming && options.onResume(id, name, chunkData) === false) { + chunked.reset(id); + chunkIdx = chunked.nextPart(id); + chunkData = handler._getChunkData(id, chunkIdx); + resuming = false; + } + if (chunkIdx == null && inProgressChunks.length === 0) { + chunked.finalize(id); + } else { + log(qq.format("Sending chunked upload request for item {}.{}, bytes {}-{} of {}.", id, chunkIdx, chunkData.start + 1, chunkData.end, size)); + options.onUploadChunk(id, name, handler._getChunkDataForCallback(chunkData)); + inProgressChunks.push(chunkIdx); + handler._getFileState(id).chunking.inProgress = inProgressChunks; + if (concurrentChunkingPossible) { + connectionManager.open(id, chunkIdx); + } + if (concurrentChunkingPossible && connectionManager.available() && handler._getFileState(id).chunking.remaining.length) { + chunked.sendNext(id); + } + if (chunkData.blob.size === 0) { + log(qq.format("Chunk {} for file {} will not be uploaded, zero sized chunk.", chunkIdx, id), "error"); + chunked.handleFailure(chunkIdx, id, "File is no longer available", null); + } else { + handler.uploadChunk(id, chunkIdx, resuming).then(function success(response, xhr) { + log("Chunked upload request succeeded for " + id + ", chunk " + chunkIdx); + handler.clearCachedChunk(id, chunkIdx); + var inProgressChunks = handler._getFileState(id).chunking.inProgress || [], responseToReport = upload.normalizeResponse(response, true), inProgressChunkIdx = qq.indexOf(inProgressChunks, chunkIdx); + log(qq.format("Chunk {} for file {} uploaded successfully.", chunkIdx, id)); + chunked.done(id, chunkIdx, responseToReport, xhr); + if (inProgressChunkIdx >= 0) { + inProgressChunks.splice(inProgressChunkIdx, 1); + } + handler._maybePersistChunkedState(id); + if (!chunked.hasMoreParts(id) && inProgressChunks.length === 0) { + chunked.finalize(id); + } else if (chunked.hasMoreParts(id)) { + chunked.sendNext(id); + } else { + log(qq.format("File ID {} has no more chunks to send and these chunk indexes are still marked as in-progress: {}", id, JSON.stringify(inProgressChunks))); + } + }, function failure(response, xhr) { + chunked.handleFailure(chunkIdx, id, response, xhr); + }).done(function() { + handler.clearXhr(id, chunkIdx); + }); + } + } + } + }, connectionManager = { + _open: [], + _openChunks: {}, + _waiting: [], + available: function() { + var max = options.maxConnections, openChunkEntriesCount = 0, openChunksCount = 0; + qq.each(connectionManager._openChunks, function(fileId, openChunkIndexes) { + openChunkEntriesCount++; + openChunksCount += openChunkIndexes.length; + }); + return max - (connectionManager._open.length - openChunkEntriesCount + openChunksCount); + }, + free: function(id, dontAllowNext) { + var allowNext = !dontAllowNext, waitingIndex = qq.indexOf(connectionManager._waiting, id), connectionsIndex = qq.indexOf(connectionManager._open, id), nextId; + delete connectionManager._openChunks[id]; + if (upload.getProxyOrBlob(id) instanceof qq.BlobProxy) { + log("Generated blob upload has ended for " + id + ", disposing generated blob."); + delete handler._getFileState(id).file; + } + if (waitingIndex >= 0) { + connectionManager._waiting.splice(waitingIndex, 1); + } else if (allowNext && connectionsIndex >= 0) { + connectionManager._open.splice(connectionsIndex, 1); + nextId = connectionManager._waiting.shift(); + if (nextId >= 0) { + connectionManager._open.push(nextId); + upload.start(nextId); + } + } + }, + getWaitingOrConnected: function() { + var waitingOrConnected = []; + qq.each(connectionManager._openChunks, function(fileId, chunks) { + if (chunks && chunks.length) { + waitingOrConnected.push(parseInt(fileId)); + } + }); + qq.each(connectionManager._open, function(idx, fileId) { + if (!connectionManager._openChunks[fileId]) { + waitingOrConnected.push(parseInt(fileId)); + } + }); + waitingOrConnected = waitingOrConnected.concat(connectionManager._waiting); + return waitingOrConnected; + }, + isUsingConnection: function(id) { + return qq.indexOf(connectionManager._open, id) >= 0; + }, + open: function(id, chunkIdx) { + if (chunkIdx == null) { + connectionManager._waiting.push(id); + } + if (connectionManager.available()) { + if (chunkIdx == null) { + connectionManager._waiting.pop(); + connectionManager._open.push(id); + } else { + (function() { + var openChunksEntry = connectionManager._openChunks[id] || []; + openChunksEntry.push(chunkIdx); + connectionManager._openChunks[id] = openChunksEntry; + })(); + } + return true; + } + return false; + }, + reset: function() { + connectionManager._waiting = []; + connectionManager._open = []; + } + }, simple = { + send: function(id, name) { + handler._getFileState(id).loaded = 0; + log("Sending simple upload request for " + id); + handler.uploadFile(id).then(function(response, optXhr) { + log("Simple upload request succeeded for " + id); + var responseToReport = upload.normalizeResponse(response, true), size = options.getSize(id); + options.onProgress(id, name, size, size); + upload.maybeNewUuid(id, responseToReport); + upload.cleanup(id, responseToReport, optXhr); + }, function(response, optXhr) { + log("Simple upload request failed for " + id); + var responseToReport = upload.normalizeResponse(response, false); + if (!options.onAutoRetry(id, name, responseToReport, optXhr)) { + upload.cleanup(id, responseToReport, optXhr); + } + }); + } + }, upload = { + cancel: function(id) { + log("Cancelling " + id); + options.paramsStore.remove(id); + connectionManager.free(id); + }, + cleanup: function(id, response, optXhr) { + var name = options.getName(id); + options.onComplete(id, name, response, optXhr); + if (handler._getFileState(id)) { + handler._clearXhrs && handler._clearXhrs(id); + } + connectionManager.free(id); + }, + getProxyOrBlob: function(id) { + return handler.getProxy && handler.getProxy(id) || handler.getFile && handler.getFile(id); + }, + initHandler: function() { + var handlerType = namespace ? qq[namespace] : qq.traditional, handlerModuleSubtype = qq.supportedFeatures.ajaxUploading ? "Xhr" : "Form"; + handler = new handlerType[handlerModuleSubtype + "UploadHandler"](options, { + getDataByUuid: options.getDataByUuid, + getName: options.getName, + getSize: options.getSize, + getUuid: options.getUuid, + log: log, + onCancel: options.onCancel, + onProgress: options.onProgress, + onUuidChanged: options.onUuidChanged + }); + if (handler._removeExpiredChunkingRecords) { + handler._removeExpiredChunkingRecords(); + } + }, + isDeferredEligibleForUpload: function(id) { + return options.isQueued(id); + }, + maybeDefer: function(id, blob) { + if (blob && !handler.getFile(id) && blob instanceof qq.BlobProxy) { + options.onUploadPrep(id); + log("Attempting to generate a blob on-demand for " + id); + blob.create().then(function(generatedBlob) { + log("Generated an on-demand blob for " + id); + handler.updateBlob(id, generatedBlob); + options.setSize(id, generatedBlob.size); + handler.reevaluateChunking(id); + upload.maybeSendDeferredFiles(id); + }, function(errorMessage) { + var errorResponse = {}; + if (errorMessage) { + errorResponse.error = errorMessage; + } + log(qq.format("Failed to generate blob for ID {}. Error message: {}.", id, errorMessage), "error"); + options.onComplete(id, options.getName(id), qq.extend(errorResponse, preventRetryResponse), null); + upload.maybeSendDeferredFiles(id); + connectionManager.free(id); + }); + } else { + return upload.maybeSendDeferredFiles(id); + } + return false; + }, + maybeSendDeferredFiles: function(id) { + var idsInGroup = options.getIdsInProxyGroup(id), uploadedThisId = false; + if (idsInGroup && idsInGroup.length) { + log("Maybe ready to upload proxy group file " + id); + qq.each(idsInGroup, function(idx, idInGroup) { + if (upload.isDeferredEligibleForUpload(idInGroup) && !!handler.getFile(idInGroup)) { + uploadedThisId = idInGroup === id; + upload.now(idInGroup); + } else if (upload.isDeferredEligibleForUpload(idInGroup)) { + return false; + } + }); + } else { + uploadedThisId = true; + upload.now(id); + } + return uploadedThisId; + }, + maybeNewUuid: function(id, response) { + if (response.newUuid !== undefined) { + options.onUuidChanged(id, response.newUuid); + } + }, + normalizeResponse: function(originalResponse, successful) { + var response = originalResponse; + if (!qq.isObject(originalResponse)) { + response = {}; + if (qq.isString(originalResponse) && !successful) { + response.error = originalResponse; + } + } + response.success = successful; + return response; + }, + now: function(id) { + var name = options.getName(id); + if (!controller.isValid(id)) { + throw new qq.Error(id + " is not a valid file ID to upload!"); + } + options.onUpload(id, name); + if (chunkingPossible && handler._shouldChunkThisFile(id)) { + chunked.sendNext(id); + } else { + simple.send(id, name); + } + }, + start: function(id) { + var blobToUpload = upload.getProxyOrBlob(id); + if (blobToUpload) { + return upload.maybeDefer(id, blobToUpload); + } else { + upload.now(id); + return true; + } + } + }; + qq.extend(this, { + add: function(id, file) { + handler.add.apply(this, arguments); + }, + upload: function(id) { + if (connectionManager.open(id)) { + return upload.start(id); + } + return false; + }, + retry: function(id) { + if (concurrentChunkingPossible) { + handler._getFileState(id).temp.ignoreFailure = false; + } + if (connectionManager.isUsingConnection(id)) { + return upload.start(id); + } else { + return controller.upload(id); + } + }, + cancel: function(id) { + var cancelRetVal = handler.cancel(id); + if (qq.isGenericPromise(cancelRetVal)) { + cancelRetVal.then(function() { + upload.cancel(id); + }); + } else if (cancelRetVal !== false) { + upload.cancel(id); + } + }, + cancelAll: function() { + var waitingOrConnected = connectionManager.getWaitingOrConnected(), i; + if (waitingOrConnected.length) { + for (i = waitingOrConnected.length - 1; i >= 0; i--) { + controller.cancel(waitingOrConnected[i]); + } + } + connectionManager.reset(); + }, + getFile: function(id) { + if (handler.getProxy && handler.getProxy(id)) { + return handler.getProxy(id).referenceBlob; + } + return handler.getFile && handler.getFile(id); + }, + isProxied: function(id) { + return !!(handler.getProxy && handler.getProxy(id)); + }, + getInput: function(id) { + if (handler.getInput) { + return handler.getInput(id); + } + }, + reset: function() { + log("Resetting upload handler"); + controller.cancelAll(); + connectionManager.reset(); + handler.reset(); + }, + expunge: function(id) { + if (controller.isValid(id)) { + return handler.expunge(id); + } + }, + isValid: function(id) { + return handler.isValid(id); + }, + getResumableFilesData: function() { + if (handler.getResumableFilesData) { + return handler.getResumableFilesData(); + } + return []; + }, + getThirdPartyFileId: function(id) { + if (controller.isValid(id)) { + return handler.getThirdPartyFileId(id); + } + }, + pause: function(id) { + if (controller.isResumable(id) && handler.pause && controller.isValid(id) && handler.pause(id)) { + connectionManager.free(id); + handler.moveInProgressToRemaining(id); + return true; + } + return false; + }, + isResumable: function(id) { + return !!handler.isResumable && handler.isResumable(id); + } + }); + qq.extend(options, o); + log = options.log; + chunkingPossible = options.chunking.enabled && qq.supportedFeatures.chunking; + concurrentChunkingPossible = chunkingPossible && options.chunking.concurrent.enabled; + preventRetryResponse = function() { + var response = {}; + response[options.preventRetryParam] = true; + return response; + }(); + upload.initHandler(); + }; + qq.WindowReceiveMessage = function(o) { + "use strict"; + var options = { + log: function(message, level) {} + }, callbackWrapperDetachers = {}; + qq.extend(options, o); + qq.extend(this, { + receiveMessage: function(id, callback) { + var onMessageCallbackWrapper = function(event) { + callback(event.data); + }; + if (window.postMessage) { + callbackWrapperDetachers[id] = qq(window).attach("message", onMessageCallbackWrapper); + } else { + log("iframe message passing not supported in this browser!", "error"); + } + }, + stopReceivingMessages: function(id) { + if (window.postMessage) { + var detacher = callbackWrapperDetachers[id]; + if (detacher) { + detacher(); + } + } + } + }); + }; + qq.FormUploadHandler = function(spec) { + "use strict"; + var options = spec.options, handler = this, proxy = spec.proxy, formHandlerInstanceId = qq.getUniqueId(), onloadCallbacks = {}, detachLoadEvents = {}, postMessageCallbackTimers = {}, isCors = options.isCors, inputName = options.inputName, getUuid = proxy.getUuid, log = proxy.log, corsMessageReceiver = new qq.WindowReceiveMessage({ + log: log + }); + function expungeFile(id) { + delete detachLoadEvents[id]; + if (isCors) { + clearTimeout(postMessageCallbackTimers[id]); + delete postMessageCallbackTimers[id]; + corsMessageReceiver.stopReceivingMessages(id); + } + var iframe = document.getElementById(handler._getIframeName(id)); + if (iframe) { + iframe.setAttribute("src", "javascript:false;"); + qq(iframe).remove(); + } + } + function getFileIdForIframeName(iframeName) { + return iframeName.split("_")[0]; + } + function initIframeForUpload(name) { + var iframe = qq.toElement("