diff --git a/CHANGELOG b/CHANGELOG index 912558317..c8f62c075 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -96,6 +96,12 @@ - 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 + -------------------------------------------------------------------------------- Changes in version 4.3.32 -------------------------------------------------------------------------------- diff --git a/SeedDMS_Core/Core/inc.ClassAttribute.php b/SeedDMS_Core/Core/inc.ClassAttribute.php index f3afdc3d9..652b8c669 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 c1aecad96..dab03f541 100644 --- a/SeedDMS_Core/Core/inc.ClassDMS.php +++ b/SeedDMS_Core/Core/inc.ClassDMS.php @@ -490,7 +490,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; @@ -512,7 +512,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; @@ -693,7 +693,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; @@ -1608,7 +1608,7 @@ class SeedDMS_Core_DMS { if($searchKey || $searchOwner || $searchCategories || $searchCreateDate || $searchExpirationDate || $searchAttributes || $status || $reception) { // 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"]; @@ -1702,7 +1702,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"; @@ -1728,7 +1728,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) @@ -1762,7 +1762,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) @@ -1773,7 +1773,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) @@ -1879,7 +1879,7 @@ class SeedDMS_Core_DMS { $pwdexpiration = 'NULL'; else $pwdexpiration = $db->qstr($pwdexpiration); - $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)."', ".$pwdexpiration.", '".intval($quota)."', ".($homefolder ? intval($homefolder) : "NULL").")"; + $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)."', ".$pwdexpiration.", '".intval($quota)."', ".($homefolder ? intval($homefolder) : "NULL").")"; $res = $this->db->getResult($queryStr); if (!$res) return false; @@ -1942,7 +1942,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; @@ -2067,7 +2067,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; @@ -2079,7 +2079,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; @@ -2091,9 +2091,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) @@ -2113,9 +2113,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) @@ -2135,7 +2135,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; @@ -2156,7 +2156,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; @@ -2168,7 +2168,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) @@ -2195,7 +2195,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; @@ -2211,7 +2211,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; @@ -2263,7 +2263,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; @@ -2279,7 +2279,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; @@ -2299,7 +2299,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; @@ -2318,7 +2318,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; @@ -2342,7 +2342,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; @@ -2362,14 +2362,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) @@ -2409,7 +2409,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; @@ -2423,13 +2423,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) @@ -2456,7 +2456,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) @@ -2482,7 +2482,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) @@ -2510,7 +2510,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; @@ -2530,7 +2530,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; @@ -2552,7 +2552,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) @@ -2575,7 +2575,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) @@ -2603,7 +2603,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; @@ -2623,7 +2623,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; @@ -2647,7 +2647,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; @@ -2666,7 +2666,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) @@ -2693,7 +2693,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; @@ -2713,7 +2713,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; @@ -2774,7 +2774,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; @@ -2798,7 +2798,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; @@ -2822,7 +2822,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; @@ -2846,7 +2846,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 LIMIT 1000"; + $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` LIMIT 1000"; $resArr = $this->db->getResultArray($queryStr); if (!$resArr) return false; @@ -2878,29 +2878,29 @@ 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`"; $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`"; $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, b.`statusid`) a left join `tblDocumentStatusLog` b on a.maxlog=b.`statusLogId` group by b.`status`"; $resArr = $this->db->getResultArray($queryStr); if (!$resArr) return false; @@ -2930,7 +2930,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`"; $resArr = $this->db->getResultArray($queryStr); if (!$resArr) return false; @@ -2960,7 +2960,7 @@ class SeedDMS_Core_DMS { $startts = mktime(24, 0, 0); $timeline = array(); - $queryStr = "SELECT document FROM tblDocumentContent WHERE date > ".$startts." AND date < ".$endts; + $queryStr = "SELECT `document` FROM `tblDocumentContent` 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 9379ea3fd..3e9dfdcf7 100644 --- a/SeedDMS_Core/Core/inc.ClassDocument.php +++ b/SeedDMS_Core/Core/inc.ClassDocument.php @@ -231,7 +231,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ 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; @@ -240,7 +240,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. @@ -288,7 +288,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; @@ -311,7 +311,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; @@ -324,7 +324,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; @@ -341,7 +341,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; @@ -366,14 +366,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; @@ -411,7 +411,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; @@ -445,7 +445,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(); @@ -460,7 +460,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; @@ -490,7 +490,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ $oldOwner = self::getOwner(); $db->startTransaction(); - $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)) { $db->rollbackTransaction(); return false; @@ -498,13 +498,13 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ /* FIXME: Update also all locks and checkouts done by the previous owner */ /* - $queryStr = "UPDATE tblDocumentLocks set userID = " . $newOwner->getID() . " WHERE document = " . $this->_id . " AND userID = " . $oldOwner->getID(); + $queryStr = "UPDATE `tblDocumentLocks` set `userID` = " . $newOwner->getID() . " WHERE `document` = " . $this->_id . " AND `userID` = " . $oldOwner->getID(); if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; } - $queryStr = "UPDATE tblDocumentCheckOuts set userID = " . $newOwner->getID() . " WHERE document = " . $this->_id . " AND userID = " . $oldOwner->getID(); + $queryStr = "UPDATE `tblDocumentCheckOuts` set `userID` = " . $newOwner->getID() . " WHERE `document` = " . $this->_id . " AND `userID` = " . $oldOwner->getID(); if (!$db->getResult($queryStr)) { $db->rollbackTransaction(); return false; @@ -539,7 +539,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; @@ -570,7 +570,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; @@ -621,7 +621,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; @@ -719,10 +719,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 { @@ -974,7 +974,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; @@ -991,7 +991,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; @@ -1041,8 +1041,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; @@ -1073,9 +1073,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; @@ -1103,9 +1103,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; @@ -1130,9 +1130,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; @@ -1270,7 +1270,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; @@ -1421,7 +1421,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; @@ -1493,7 +1493,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; @@ -1537,7 +1537,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; @@ -1549,7 +1549,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(); @@ -1706,7 +1706,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; @@ -1736,7 +1736,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; @@ -1768,7 +1768,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; @@ -1812,7 +1812,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; @@ -1836,7 +1836,7 @@ class SeedDMS_Core_Document extends SeedDMS_Core_Object { /* {{{ */ function __getLatestContent() { /* {{{ */ if (!$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 0,1"; $resArr = $db->getResultArray($queryStr); if (is_bool($resArr) && !$resArr) return false; @@ -1908,13 +1908,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; @@ -1942,7 +1942,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(); @@ -1971,7 +1971,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(); @@ -2083,7 +2083,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; @@ -2111,12 +2111,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).")"; } @@ -2155,12 +2155,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).")"; } @@ -2183,7 +2183,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; @@ -2196,7 +2196,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; @@ -2207,7 +2207,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; @@ -2219,7 +2219,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; @@ -2237,7 +2237,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; @@ -2273,7 +2273,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; @@ -2341,49 +2341,49 @@ 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 tblDocumentCheckOuts WHERE document = " . $this->_id; + $queryStr = "DELETE FROM `tblDocumentCheckOuts` 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; @@ -2551,7 +2551,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; @@ -2581,7 +2581,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; @@ -2600,7 +2600,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; @@ -2633,7 +2633,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; @@ -2833,7 +2833,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; @@ -2855,7 +2855,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; @@ -2876,7 +2876,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; @@ -2887,7 +2887,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; @@ -3392,7 +3392,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) @@ -4838,7 +4838,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; } @@ -4865,9 +4865,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; @@ -4889,7 +4889,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; @@ -4920,9 +4920,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; @@ -4991,7 +4991,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; @@ -5034,7 +5034,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() ."' "; @@ -5044,7 +5044,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() ."' "; @@ -5076,7 +5076,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() ."' "; @@ -5111,7 +5111,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; } @@ -5143,7 +5143,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); @@ -5202,7 +5202,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) @@ -5351,7 +5351,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; @@ -5482,7 +5482,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`"; @@ -5517,7 +5517,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 8e6245dde..3d93b1e59 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; @@ -820,7 +820,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(); @@ -890,30 +890,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; @@ -1007,8 +1007,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; @@ -1035,7 +1035,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; @@ -1060,9 +1060,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; @@ -1090,9 +1090,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; @@ -1109,9 +1109,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; @@ -1241,7 +1241,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; @@ -1303,7 +1303,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)); @@ -1398,7 +1398,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; @@ -1472,7 +1472,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; @@ -1633,7 +1633,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; @@ -1662,7 +1662,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 3c8afed0f..3e0881fe2 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; @@ -193,7 +193,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; @@ -205,7 +205,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; @@ -230,8 +230,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); @@ -252,8 +252,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; @@ -273,37 +273,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; @@ -508,11 +508,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 0369cd2ed..3bd711b08 100644 --- a/SeedDMS_Core/Core/inc.ClassUser.php +++ b/SeedDMS_Core/Core/inc.ClassUser.php @@ -411,15 +411,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); @@ -440,9 +440,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) @@ -472,7 +472,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; @@ -486,7 +486,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; @@ -500,7 +500,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; @@ -529,9 +529,9 @@ class SeedDMS_Core_User { /* {{{ */ $db = $this->_dms->getDB(); if(trim($newPwdExpiration) == '') - $queryStr = "UPDATE tblUsers SET pwdExpiration = NULL WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblUsers` SET `pwdExpiration` = NULL WHERE `id` = " . $this->_id; else - $queryStr = "UPDATE tblUsers SET pwdExpiration =".$db->qstr($newPwdExpiration)." WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblUsers` SET `pwdExpiration` =".$db->qstr($newPwdExpiration)." WHERE id = " . $this->_id; $res = $db->getResult($queryStr); if (!$res) return false; @@ -545,7 +545,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; @@ -559,7 +559,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; @@ -573,7 +573,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; @@ -587,7 +587,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; @@ -602,9 +602,9 @@ class SeedDMS_Core_User { /* {{{ */ $db = $this->_dms->getDB(); if(is_object($newrole)) - $queryStr = "UPDATE tblUsers SET role = " . $newrole->getID() . " WHERE id = " . $this->_id; + $queryStr = "UPDATE `tblUsers` SET `role` = " . $newrole->getID() . " WHERE `id` = " . $this->_id; else - $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; @@ -620,7 +620,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; @@ -636,7 +636,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; @@ -650,7 +650,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; @@ -664,7 +664,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; @@ -676,7 +676,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; @@ -687,7 +687,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; @@ -705,7 +705,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; @@ -719,7 +719,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; @@ -732,7 +732,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; @@ -766,10 +766,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)) @@ -781,147 +781,147 @@ 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; @@ -1067,7 +1067,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; @@ -1087,7 +1087,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; @@ -1106,9 +1106,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; @@ -1564,11 +1564,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) @@ -1580,11 +1580,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) @@ -1611,7 +1611,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; @@ -1627,7 +1627,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; @@ -1645,7 +1645,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; @@ -1668,7 +1668,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; @@ -1695,21 +1695,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; } @@ -1729,21 +1729,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; } @@ -1759,11 +1759,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; } /* }}} */ @@ -1779,14 +1779,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(); @@ -1805,7 +1805,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; } /* }}} */ @@ -1818,7 +1818,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; } /* }}} */ @@ -1830,7 +1830,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 9b06406d3..2d3ee3231 100644 --- a/SeedDMS_Core/Core/inc.ClassWorkflow.php +++ b/SeedDMS_Core/Core/inc.ClassWorkflow.php @@ -83,7 +83,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; @@ -97,7 +97,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; @@ -126,7 +126,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; @@ -187,7 +187,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; @@ -211,7 +211,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; @@ -236,7 +236,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; @@ -276,7 +276,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; @@ -289,7 +289,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; @@ -297,7 +297,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; @@ -316,7 +316,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; @@ -367,20 +367,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; @@ -465,7 +465,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; @@ -479,7 +479,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; @@ -493,7 +493,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; @@ -515,7 +515,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; @@ -532,7 +532,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; @@ -547,7 +547,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; @@ -577,7 +577,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; @@ -638,7 +638,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; @@ -655,7 +655,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; @@ -670,7 +670,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; @@ -700,7 +700,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; @@ -807,7 +807,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; @@ -821,7 +821,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; @@ -835,7 +835,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; @@ -849,7 +849,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; @@ -863,7 +863,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; @@ -883,7 +883,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; @@ -911,7 +911,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; @@ -940,7 +940,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 95935ca4b..9271f1d57 100644 --- a/SeedDMS_Core/Core/inc.DBAccessPDO.php +++ b/SeedDMS_Core/Core/inc.DBAccessPDO.php @@ -227,6 +227,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 * diff --git a/inc/inc.Calendar.php b/inc/inc.Calendar.php index 9ce19ae07..36b7ca8eb 100644 --- a/inc/inc.Calendar.php +++ b/inc/inc.Calendar.php @@ -28,7 +28,7 @@ function getEvents($day, $month, $year){ $date = mktime(12,0,0, $month, $day, $year); - $queryStr = "SELECT * FROM tblEvents WHERE start <= " . $date . " AND stop >= " . $date; + $queryStr = "SELECT * FROM `tblEvents` WHERE `start` <= " . $date . " AND `stop` >= " . $date; $ret = $db->getResultArray($queryStr); return $ret; } @@ -37,9 +37,9 @@ 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 . " )"; + $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; } @@ -48,7 +48,7 @@ function addEvent($from, $to, $name, $comment ){ global $db,$user; - $queryStr = "INSERT INTO tblEvents (name, comment, start, stop, date, userID) VALUES ". + $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); @@ -61,7 +61,7 @@ function getEvent($id){ global $db; - $queryStr = "SELECT * FROM tblEvents WHERE id = " . (int) $id; + $queryStr = "SELECT * FROM `tblEvents` WHERE `id` = " . (int) $id; $ret = $db->getResultArray($queryStr); if (is_bool($ret) && $ret == false) return false; @@ -76,7 +76,7 @@ function editEvent($id, $from, $to, $name, $comment ){ 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; + $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; } @@ -87,7 +87,7 @@ function delEvent($id){ global $db; - $queryStr = "DELETE FROM tblEvents WHERE id = " . (int) $id; + $queryStr = "DELETE FROM `tblEvents` WHERE `id` = " . (int) $id; $ret = $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 564ecc6ec..566c7379c 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; } @@ -187,7 +187,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; @@ -203,7 +203,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; @@ -228,7 +228,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; @@ -244,7 +244,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; @@ -269,7 +269,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; @@ -302,7 +302,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; } @@ -327,7 +327,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; } @@ -341,7 +341,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; @@ -355,7 +355,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; @@ -371,7 +371,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'] = ''; @@ -439,7 +439,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; @@ -454,7 +454,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; @@ -474,7 +474,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/install/create_tables-innodb.sql b/install/create_tables-innodb.sql index e3ccac588..9ef8b62a7 100644 --- a/install/create_tables-innodb.sql +++ b/install/create_tables-innodb.sql @@ -170,7 +170,7 @@ CREATE TABLE `tblFolders` ( 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`); -- -------------------------------------------------------- @@ -672,7 +672,7 @@ CREATE TABLE `tblEvents` ( -- Table structure for workflow states -- -CREATE TABLE tblWorkflowStates ( +CREATE TABLE `tblWorkflowStates` ( `id` int(11) NOT NULL auto_increment, `name` text NOT NULL, `visibility` smallint(5) DEFAULT 0, @@ -688,7 +688,7 @@ CREATE TABLE tblWorkflowStates ( -- Table structure for workflow actions -- -CREATE TABLE tblWorkflowActions ( +CREATE TABLE `tblWorkflowActions` ( `id` int(11) NOT NULL auto_increment, `name` text NOT NULL, PRIMARY KEY (`id`) @@ -700,7 +700,7 @@ CREATE TABLE tblWorkflowActions ( -- Table structure for workflows -- -CREATE TABLE tblWorkflows ( +CREATE TABLE `tblWorkflows` ( `id` int(11) NOT NULL auto_increment, `name` text NOT NULL, `initstate` int(11) NOT NULL, @@ -715,7 +715,7 @@ CREATE TABLE tblWorkflows ( -- Table structure for workflow transitions -- -CREATE TABLE tblWorkflowTransitions ( +CREATE TABLE `tblWorkflowTransitions` ( `id` int(11) NOT NULL auto_increment, `workflow` int(11) default NULL, `state` int(11) default NULL, @@ -735,7 +735,7 @@ CREATE TABLE tblWorkflowTransitions ( -- Table structure for workflow transition users -- -CREATE TABLE tblWorkflowTransitionUsers ( +CREATE TABLE `tblWorkflowTransitionUsers` ( `id` int(11) NOT NULL auto_increment, `transition` int(11) default NULL, `userid` int(11) default NULL, @@ -750,7 +750,7 @@ CREATE TABLE tblWorkflowTransitionUsers ( -- Table structure for workflow transition groups -- -CREATE TABLE tblWorkflowTransitionGroups ( +CREATE TABLE `tblWorkflowTransitionGroups` ( `id` int(11) NOT NULL auto_increment, `transition` int(11) default NULL, `groupid` int(11) default NULL, @@ -766,7 +766,7 @@ CREATE TABLE tblWorkflowTransitionGroups ( -- Table structure for workflow log -- -CREATE TABLE tblWorkflowLog ( +CREATE TABLE `tblWorkflowLog` ( `id` int(11) NOT NULL auto_increment, `document` int(11) default NULL, `version` smallint(5) default NULL, @@ -788,7 +788,7 @@ CREATE TABLE tblWorkflowLog ( -- Table structure for workflow document relation -- -CREATE TABLE tblWorkflowDocumentContent ( +CREATE TABLE `tblWorkflowDocumentContent` ( `parentworkflow` int(11) DEFAULT 0, `workflow` int(11) DEFAULT NULL, `document` int(11) DEFAULT NULL, @@ -806,7 +806,7 @@ CREATE TABLE tblWorkflowDocumentContent ( -- Table structure for mandatory workflows -- -CREATE TABLE tblWorkflowMandatoryWorkflow ( +CREATE TABLE `tblWorkflowMandatoryWorkflow` ( `userid` int(11) default NULL, `workflow` int(11) default NULL, UNIQUE(userid, workflow), @@ -941,4 +941,3 @@ INSERT INTO tblUsers VALUES (1, 'admin', '21232f297a57a5a743894a0e4a801fc3', '', INSERT INTO tblUsers VALUES (2, 'guest', NULL, '', 'Guest User', NULL, '', '', '', 2, 0, NULL, 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, 1, 0); -INSERT INTO tblCategory VALUES (0, ''); diff --git a/install/create_tables-sqlite3.sql b/install/create_tables-sqlite3.sql index 5ef61ce2c..1bb5be09c 100644 --- a/install/create_tables-sqlite3.sql +++ b/install/create_tables-sqlite3.sql @@ -586,13 +586,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 ) ; -- -------------------------------------------------------- @@ -601,7 +601,7 @@ CREATE TABLE tblWorkflowStates ( -- Table structure for workflow actions -- -CREATE TABLE tblWorkflowActions ( +CREATE TABLE `tblWorkflowActions` ( `id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` text NOT NULL ) ; @@ -612,7 +612,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, @@ -625,7 +625,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, @@ -640,7 +640,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 @@ -652,7 +652,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, @@ -665,10 +665,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, @@ -682,11 +682,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 ) ; @@ -697,7 +697,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) @@ -787,9 +787,9 @@ CREATE TABLE `tblArosAcos` ( CREATE TABLE `tblVersion` ( `date` TEXT NOT NULL, - `major` smallint, - `minor` smallint, - `subminor` smallint + `major` INTEGER, + `minor` INTEGER, + `subminor` INTEGER ) ; -- -------------------------------------------------------- @@ -805,4 +805,3 @@ INSERT INTO tblUsers VALUES (1, 'admin', '21232f297a57a5a743894a0e4a801fc3', '', 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, 1, 0); -INSERT INTO tblCategory VALUES (0, ''); diff --git a/languages/ar_EG/lang.inc b/languages/ar_EG/lang.inc index ef963df37..dd3db57ca 100644 --- a/languages/ar_EG/lang.inc +++ b/languages/ar_EG/lang.inc @@ -842,6 +842,7 @@ Parent folder: [folder_path] مستخدم: [username] URL: [url]', 'removed_workflow_email_subject' => '[sitename]: [name] - تم ازالة مسار العمل من اصدار المستند', +'removeFolderFromDropFolder' => '', 'remove_marked_files' => 'ازالة الملفات المختارة', 'repaired' => 'تم اصلاحه', 'repairing_objects' => 'تحضير المستندات والمجلدات.', diff --git a/languages/bg_BG/lang.inc b/languages/bg_BG/lang.inc index 0db8f8784..62aa7ef0e 100644 --- a/languages/bg_BG/lang.inc +++ b/languages/bg_BG/lang.inc @@ -734,6 +734,7 @@ $text = array( 'removed_revispr' => '', 'removed_workflow_email_body' => '', 'removed_workflow_email_subject' => '', +'removeFolderFromDropFolder' => '', 'remove_marked_files' => '', 'repaired' => '', 'repairing_objects' => 'Поправка на папки и документи', diff --git a/languages/ca_ES/lang.inc b/languages/ca_ES/lang.inc index e7f5e47d7..678aadcfa 100644 --- a/languages/ca_ES/lang.inc +++ b/languages/ca_ES/lang.inc @@ -739,6 +739,7 @@ URL: [url]', 'removed_revispr' => '', 'removed_workflow_email_body' => '', 'removed_workflow_email_subject' => '', +'removeFolderFromDropFolder' => '', 'remove_marked_files' => '', 'repaired' => '', 'repairing_objects' => '', diff --git a/languages/cs_CZ/lang.inc b/languages/cs_CZ/lang.inc index 66612025e..8ae6c4d80 100644 --- a/languages/cs_CZ/lang.inc +++ b/languages/cs_CZ/lang.inc @@ -852,6 +852,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.', diff --git a/languages/de_DE/lang.inc b/languages/de_DE/lang.inc index b7c1b3d5b..bbe50a73f 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 (2367), dgrutsch (22) $text = array( '2_factor_auth' => '2-Faktor Authentifizierung', @@ -872,6 +872,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.', diff --git a/languages/el_GR/lang.inc b/languages/el_GR/lang.inc index ad93374b1..b82208ffb 100644 --- a/languages/el_GR/lang.inc +++ b/languages/el_GR/lang.inc @@ -745,6 +745,7 @@ URL: [url]', 'removed_revispr' => '', 'removed_workflow_email_body' => '', 'removed_workflow_email_subject' => '', +'removeFolderFromDropFolder' => '', 'remove_marked_files' => '', 'repaired' => '', 'repairing_objects' => '', diff --git a/languages/en_GB/lang.inc b/languages/en_GB/lang.inc index aff121206..8dc3474f8 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 (1494), dgrutsch (9), netixw (14) $text = array( '2_factor_auth' => '2-factor authentication', @@ -873,6 +873,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.', diff --git a/languages/es_ES/lang.inc b/languages/es_ES/lang.inc index d56dd21e4..4d4c36464 100644 --- a/languages/es_ES/lang.inc +++ b/languages/es_ES/lang.inc @@ -857,6 +857,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.', diff --git a/languages/fr_FR/lang.inc b/languages/fr_FR/lang.inc index 5d7238384..08c29f8ad 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 (1058), jeromerobert (50), lonnnew (9), Oudiceval (175) $text = array( '2_factor_auth' => 'Authentification forte', @@ -859,6 +859,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.', @@ -1044,8 +1045,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', @@ -1156,7 +1157,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 +1222,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)', diff --git a/languages/hr_HR/lang.inc b/languages/hr_HR/lang.inc index c7ca21f5e..6eab1ee34 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' => '', @@ -861,6 +861,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.', @@ -1042,7 +1043,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 +1061,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 +1223,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 +1271,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!', diff --git a/languages/hu_HU/lang.inc b/languages/hu_HU/lang.inc index 9ae96862e..94a874b9d 100644 --- a/languages/hu_HU/lang.inc +++ b/languages/hu_HU/lang.inc @@ -857,6 +857,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', diff --git a/languages/it_IT/lang.inc b/languages/it_IT/lang.inc index 382559be4..3a9f896f6 100644 --- a/languages/it_IT/lang.inc +++ b/languages/it_IT/lang.inc @@ -868,6 +868,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...', diff --git a/languages/ko_KR/lang.inc b/languages/ko_KR/lang.inc index f8ae12238..b336b4da3 100644 --- a/languages/ko_KR/lang.inc +++ b/languages/ko_KR/lang.inc @@ -854,6 +854,7 @@ URL : [url]', 사용자: [username] URL: [url]', 'removed_workflow_email_subject' => '[sitename] : [name] - 문서 버전에서 제거 된 워크플로우', +'removeFolderFromDropFolder' => '', 'remove_marked_files' => '마크 파일을 제거', 'repaired' => '복구', 'repairing_objects' => '문서 및 폴더 복구', diff --git a/languages/nl_NL/lang.inc b/languages/nl_NL/lang.inc index 139e9a822..05eea6454 100644 --- a/languages/nl_NL/lang.inc +++ b/languages/nl_NL/lang.inc @@ -859,6 +859,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.', diff --git a/languages/pl_PL/lang.inc b/languages/pl_PL/lang.inc index 1fd9926d9..4dad041b4 100644 --- a/languages/pl_PL/lang.inc +++ b/languages/pl_PL/lang.inc @@ -850,6 +850,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.', diff --git a/languages/pt_BR/lang.inc b/languages/pt_BR/lang.inc index 2b4ff6e33..0855361a7 100644 --- a/languages/pt_BR/lang.inc +++ b/languages/pt_BR/lang.inc @@ -855,6 +855,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', diff --git a/languages/ro_RO/lang.inc b/languages/ro_RO/lang.inc index 0eed5ad8e..f7036ff71 100644 --- a/languages/ro_RO/lang.inc +++ b/languages/ro_RO/lang.inc @@ -862,6 +862,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.', diff --git a/languages/ru_RU/lang.inc b/languages/ru_RU/lang.inc index e85f6448e..df001d501 100644 --- a/languages/ru_RU/lang.inc +++ b/languages/ru_RU/lang.inc @@ -864,6 +864,7 @@ URL: [url]', Пользователь: [username] URL: [url]', 'removed_workflow_email_subject' => '[sitename]: удалён процесс из версии документа «[name]»', +'removeFolderFromDropFolder' => '', 'remove_marked_files' => 'Удалить выбранные файлы', 'repaired' => 'исправлено', 'repairing_objects' => 'Восстановление каталогов и документов', diff --git a/languages/sk_SK/lang.inc b/languages/sk_SK/lang.inc index ebe8543f3..6cc0b43b1 100644 --- a/languages/sk_SK/lang.inc +++ b/languages/sk_SK/lang.inc @@ -738,6 +738,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' => '', diff --git a/languages/sv_SE/lang.inc b/languages/sv_SE/lang.inc index 49ae7ce04..a1b8bcb1e 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' => '', @@ -603,7 +603,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 +750,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' => '', @@ -842,6 +842,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.', diff --git a/languages/tr_TR/lang.inc b/languages/tr_TR/lang.inc index 9e89d5f76..981cb4913 100644 --- a/languages/tr_TR/lang.inc +++ b/languages/tr_TR/lang.inc @@ -858,6 +858,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.', diff --git a/languages/uk_UA/lang.inc b/languages/uk_UA/lang.inc index e620c91d9..e2d885a6d 100644 --- a/languages/uk_UA/lang.inc +++ b/languages/uk_UA/lang.inc @@ -864,6 +864,7 @@ URL: [url]', Користувач: [username] URL: [url]', 'removed_workflow_email_subject' => '[sitename]: видалено процес з версії документа «[name]»', +'removeFolderFromDropFolder' => '', 'remove_marked_files' => 'Видалити обрані файли', 'repaired' => 'виправлено', 'repairing_objects' => 'Відновлення каталогів і документів', diff --git a/languages/zh_CN/lang.inc b/languages/zh_CN/lang.inc index 710202cd4..2c3786fc3 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 (654), fengjohn (5) $text = array( '2_factor_auth' => '', @@ -694,7 +694,7 @@ URL: [url]', 'password_send' => '', 'password_send_text' => '', 'password_strength' => '密码强度', -'password_strength_insuffient' => '', +'password_strength_insuffient' => '密码强度不够', 'password_wrong' => '', 'pending_approvals' => '', 'pending_reviews' => '', @@ -740,6 +740,7 @@ URL: [url]', 'removed_revispr' => '', 'removed_workflow_email_body' => '', 'removed_workflow_email_subject' => '', +'removeFolderFromDropFolder' => '', 'remove_marked_files' => '删除选中的文件', 'repaired' => '', 'repairing_objects' => '', @@ -1169,7 +1170,7 @@ URL: [url]', 'set_expiry' => '设置截止日期', 'set_owner' => '设置所有者', 'set_owner_error' => '错误 设置所有者', -'set_password' => '', +'set_password' => '设定密码', 'set_workflow' => '', 'signed_in_as' => '登录为', 'sign_in' => '', diff --git a/languages/zh_TW/lang.inc b/languages/zh_TW/lang.inc index ae0f57797..84cae9240 100644 --- a/languages/zh_TW/lang.inc +++ b/languages/zh_TW/lang.inc @@ -738,6 +738,7 @@ URL: [url]', 'removed_revispr' => '', 'removed_workflow_email_body' => '', 'removed_workflow_email_subject' => '', +'removeFolderFromDropFolder' => '', 'remove_marked_files' => '刪除勾選的檔案', 'repaired' => '', 'repairing_objects' => '', diff --git a/op/op.AddDocument.php b/op/op.AddDocument.php index 325733b42..68e578c85 100644 --- a/op/op.AddDocument.php +++ b/op/op.AddDocument.php @@ -275,6 +275,23 @@ 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; + } + } +} + if($settings->_libraryFolder) { if(isset($_POST["librarydoc"]) && $_POST["librarydoc"]) { if($clonedoc = $dms->getDocument($_POST["librarydoc"])) { @@ -330,7 +347,7 @@ 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")); } } 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.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.UpdateDocument.php b/op/op.UpdateDocument.php index d02553937..287e4fc5a 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")); 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 cc7e2e45b..3beb3a421 100644 --- a/out/out.AddEvent.php +++ b/out/out.AddEvent.php @@ -37,6 +37,7 @@ if ($user->isGuest()) { } if($view) { + $view->setParam('strictformcheck', $settings->_strictFormCheck); $view($_GET); exit; } diff --git a/out/out.AdminTools.php b/out/out.AdminTools.php index 13046d7bf..0d375ff16 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/styles/bootstrap/application.css b/styles/bootstrap/application.css index 611e4bfd7..49b6d8995 100644 --- a/styles/bootstrap/application.css +++ b/styles/bootstrap/application.css @@ -274,6 +274,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/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":"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","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":";CAAA,SAAUA,QCEV,GAAIC,IAAK,SAASC,GACd,YAEA,QACIC,KAAM,WAEF,MADAD,GAAQE,MAAMC,QAAU,OACjBC,MAIXC,OAAQ,SAASC,EAAMC,GAMnB,MALIP,GAAQQ,iBACRR,EAAQQ,iBAAiBF,EAAMC,GAAI,GAC5BP,EAAQS,aACfT,EAAQS,YAAY,KAAOH,EAAMC,GAE9B,WACHR,GAAGC,GAASU,OAAOJ,EAAMC,KAIjCG,OAAQ,SAASJ,EAAMC,GAMnB,MALIP,GAAQW,oBACRX,EAAQW,oBAAoBL,EAAMC,GAAI,GAC/BP,EAAQS,aACfT,EAAQY,YAAY,KAAON,EAAMC,GAE9BH,MAGXS,SAAU,SAASC,GAKf,QAAKA,IAKDd,IAAYc,IAIZd,EAAQa,SACDb,EAAQa,SAASC,MAGgC,EAA9CA,EAAWC,wBAAwBf,OAOrDgB,aAAc,SAASC,GAEnB,MADAA,GAASC,WAAWF,aAAahB,EAASiB,GACnCb,MAGXe,OAAQ,WAEJ,MADAnB,GAAQkB,WAAWE,YAAYpB,GACxBI,MAOXiB,IAAK,SAASC,GAEV,GAAqB,MAAjBtB,EAAQE,MACR,KAAM,IAAIH,IAAGwB,MAAM,6EAWvB,OAPsB,OAAlBD,EAAOE,SAC8B,gBAA1BxB,GAAQE,MAAMsB,SAAqD,mBAArBxB,GAAe,UACpEsB,EAAOG,OAAS,iBAAmBC,KAAKC,MAAM,IAAML,EAAOE,SAAW,KAG9EzB,GAAG6B,OAAO5B,EAAQE,MAAOoB,GAElBlB,MAGXyB,SAAU,SAASC,EAAMC,GACrB,GAAIC,GAAK,GAAIC,QAAO,QAAUH,EAAO,QACrC,OAAOE,GAAGE,KAAKlC,EAAQmC,eAAiBJ,IAAkBC,EAAGE,KAAKlC,EAAQkB,WAAWiB,aAGzFC,SAAU,SAASN,GAIf,MAHK/B,IAAGC,GAAS6B,SAASC,KACtB9B,EAAQmC,WAAa,IAAML,GAExB1B,MAGXiC,YAAa,SAASP,GAClB,GAAIE,GAAK,GAAIC,QAAO,QAAUH,EAAO,QAErC,OADA9B,GAAQmC,UAAYnC,EAAQmC,UAAUG,QAAQN,EAAI,KAAKM,QAAQ,aAAc,IACtElC,MAGXmC,WAAY,SAASJ,EAAWK,GAC5B,GAAIC,GACAC,IAEJ,OAAIF,IAASxC,EAAQ2C,cACV3C,EAAQ2C,cAAc,IAAMR,GAE9BnC,EAAQ4C,iBACN5C,EAAQ4C,iBAAiB,IAAMT,IAG1CM,EAAazC,EAAQ6C,qBAAqB,KAE1C9C,GAAG+C,KAAKL,EAAY,SAASM,EAAKC,GAC1BjD,GAAGiD,GAAKnB,SAASM,IACjBO,EAAOO,KAAKD,KAGbR,EAAQE,EAAO,GAAKA,IAG/BQ,gBAAiB,SAASf,GACtB,MAAOpC,IAAGC,GAASuC,WAAWJ,GAAW,IAG7CgB,SAAU,WAIN,IAHA,GAAIA,MACAC,EAAQpD,EAAQqD,WAEbD,GACoB,IAAnBA,EAAME,UACNH,EAASF,KAAKG,GAElBA,EAAQA,EAAMG,WAGlB,OAAOJ,IAGXK,QAAS,SAASC,GAGd,MAFAzD,GAAQ0D,UAAYD,EACpBzD,EAAQ2D,YAAcF,EACfrD,MAGXwD,UAAW,WACP,MAAO7D,IAAGC,GAASwD,QAAQ,KAK/BK,aAAc,SAASC,GACnB,GAAIC,EAEJ,OAAI/D,GAAQ6D,eAEH7D,EAAQ6D,aAAaC,IAKkC,MAArD,WAAaE,KAAKhE,EAAQiE,aAAaH,KAG9CC,EAAU/D,EAAQ8D,GAEFI,SAAZH,GAKiC,MAA9B,WAAaC,KAAKD,QAMxC,WACG,YAEAhE,IAAGoE,aAAe,SAASC,EAAQC,EAAMC,GACrC,MAAOvE,IAAGwE,cAAcH,EAAOI,UAAUH,EAAMC,KAGnDvE,GAAGwE,cAAgB,SAASE,GACxB,GAAIC,GAAaC,EAgBbC,EAAUC,EAfVC,EAAa,SAASC,EAAMV,GACxB,GAAIW,GAAcC,OAAOD,aACjBC,OAAOC,mBACPD,OAAOE,gBACPF,OAAOG,cACXC,EAAcL,GAAe,GAAIA,EAErC,OAAIK,IACAA,EAAYC,OAAOP,GACZM,EAAYE,QAAQlB,IAGpB,GAAImB,OAAMT,IAAQzE,KAAM+D,IAyB3C,OAlBIM,GADAF,EAAQgB,MAAM,KAAK,GAAGC,QAAQ,WAAa,EAC9BC,KAAKlB,EAAQgB,MAAM,KAAK,IAGxBG,UAAUnB,EAAQgB,MAAM,KAAK,IAI9CZ,EAAaJ,EAAQgB,MAAM,KAAK,GAC3BA,MAAM,KAAK,GACXA,MAAM,KAAK,GAGhBf,EAAc,GAAImB,aAAYlB,EAAWmB,QACzClB,EAAW,GAAImB,YAAWrB,GAC1B3E,GAAG+C,KAAK6B,EAAY,SAAS5B,EAAKiD,GAC9BpB,EAAS7B,GAAOiD,EAAUC,WAAW,KAGlCnB,EAAWJ,EAAaG,IAGnC9E,GAAGmG,IAAM,SAASC,EAASC,GACnBnB,OAAOoB,UACFD,GAAmB,SAAVA,EAKNnB,OAAOoB,QAAQD,GACfnB,OAAOoB,QAAQD,GAAOD,GAGtBlB,OAAOoB,QAAQH,IAAI,IAAME,EAAQ,KAAOD,GAR5ClB,OAAOoB,QAAQH,IAAIC,KAc/BpG,GAAGuG,SAAW,SAASC,GACnB,MAAOA,KAAaA,EAASjD,UAAyD,oBAA7CkD,OAAOC,UAAUC,SAASC,KAAKJ,IAG5ExG,GAAG6G,WAAa,SAASL,GACrB,MAA6B,kBAAf,IASlBxG,GAAG8G,QAAU,SAASC,GAClB,MAAiD,mBAA1CN,OAAOC,UAAUC,SAASC,KAAKG,IACjCA,GAAS7B,OAAOY,aAAeiB,EAAMC,QAAUD,EAAMC,OAAOC,cAAgBnB,aAIrF9F,GAAGkH,WAAa,SAASC,GACrB,MAAyD,kCAAlDV,OAAOC,UAAUC,SAASC,KAAKO,IAK1CnH,GAAGoH,WAAa,SAASC,GACrB,MAAyD,sBAAlDZ,OAAOC,UAAUC,SAASC,KAAKS,IAGjCA,EAAcC,MAAQD,EAAcE,WAG7CvH,GAAGwH,SAAW,SAASC,GACnB,MAAuD,oBAAhDhB,OAAOC,UAAUC,SAASC,KAAKa,IAG1CzH,GAAG0H,QAAU,SAASC,GAClB,MAAIC,QAAOlB,UAAUmB,KACVF,EAAOE,OAGXF,EAAOpF,QAAQ,aAAc,KAOxCvC,GAAG8H,OAAS,SAASC,GAEjB,GAAIC,GAAQC,MAAMvB,UAAUwB,MAAMtB,KAAKuB,UAAW,GAC9CC,EAASL,EACTM,EAAmBD,EAAOzC,QAAQ,KAetC,OAbA3F,IAAG+C,KAAKiF,EAAM,SAAShF,EAAKC,GACxB,GAAIqF,GAAYF,EAAOG,UAAU,EAAGF,GAChCG,EAAWJ,EAAOG,UAAUF,EAAmB,EAMnD,IAJAD,EAASE,EAAYrF,EAAMuF,EAC3BH,EAAmBD,EAAOzC,QAAQ,KAAM0C,EAAmBpF,EAAI8C,QAG3DsC,EAAmB,EACnB,OAAO,IAIRD,GAGXpI,GAAGyI,OAAS,SAASC,GACjB,MAAOxD,QAAOyD,MAAsD,kBAA9ClC,OAAOC,UAAUC,SAASC,KAAK8B,IAGzD1I,GAAG4I,WAAa,SAASC,GACrB,MAAO3D,QAAO4D,UAA8D,sBAAlDrC,OAAOC,UAAUC,SAASC,KAAKiC,IAG7D7I,GAAG+I,cAAgB,SAASC,GACxB,MAAOhJ,IAAGyI,OAAOO,IAAqBhJ,GAAGiJ,QAAQD,IAGrDhJ,GAAGiJ,QAAU,SAASC,EAAYC,GAC9B,GAAIC,GAAe,SAAS7I,GACxB,GAAI8I,GAAiB9I,EAAK+I,aAE1B,OAAIH,GAC0B,SAAnBE,EAGe,SAAnBA,EAGX,UAAInE,OAAOqE,kBAC4C,8BAA/C9C,OAAOC,UAAUC,SAASC,KAAKsC,IAC3BA,EAAW3I,MAAQ6I,EAAaF,EAAW3I,WAKnD2I,EAAWM,SAC8B,UAArCN,EAAWM,QAAQF,eACfJ,EAAW3I,MAAQ6I,EAAaF,EAAW3I,QAS3DP,GAAGyJ,OAAS,SAASC,GACjB,GAAIxE,OAAOO,MAAsD,kBAA9CgB,OAAOC,UAAUC,SAASC,KAAK8C,GAC9C,OAAO,GAIf1J,GAAG2J,qBAAuB,WACtB,GAAIC,GAAQC,SAASC,cAAc,QAGnC,OAFAF,GAAMrJ,KAAO,OAGU4D,SAAnByF,EAAMG,UACc,mBAATpB,OACa,mBAAbqB,WACoC,mBAAnChK,IAAGiK,oBAAqBC,QAI5ClK,GAAGiK,kBAAoB,WACnB,GAAI/E,OAAOiF,eACP,MAAO,IAAIA,eAGf,KACI,MAAO,IAAIC,eAAc,sBAE7B,MAAOC,GAEH,MADArK,IAAGmG,IAAI,wCAAyC,SACzC,OAIfnG,GAAGsK,sBAAwB,SAASC,GAChC,MAAOA,GAAaC,OAChBD,EAAaC,MAAMzE,OAAS,GAC5BwE,EAAaC,MAAM,GAAGC,kBAG9BzK,GAAG0K,wBAA0B,WACzB,OAAQ1K,GAAG2K,gBACP3K,GAAG2J,yBACuBxF,SAAzBwE,KAAKjC,UAAUwB,OAAsD/D,SAA/BwE,KAAKjC,UAAUkE,aAAyDzG,SAA5BwE,KAAKjC,UAAUmE,WAG1G7K,GAAG8K,UAAY,SAASC,EAAYC,EAAOC,GACvC,GAAIC,GAASH,EAAW7C,OAAS6C,EAAWF,UAAYE,EAAWH,WAEnE,OAAOM,GAAOtE,KAAKmE,EAAYC,EAAOC,IAG1CjL,GAAGmL,iBAAmB,SAASnE,GAC3B,GAAIoE,GAAa,GACbC,EAAQ,GAAIrF,YAAWgB,EAY3B,OAVAhH,IAAG+C,KAAKsI,EAAO,SAASrI,EAAKsI,GACzB,GAAIC,GAAeD,EAAI3E,SAAS,GAE5B4E,GAAaxF,OAAS,IACtBwF,EAAe,IAAMA,GAGzBH,GAAcG,IAGXH,GAGXpL,GAAGwL,cAAgB,SAASC,EAAMC,EAAa3F,GAC3C,GAAI4F,GAAc3L,GAAG8K,UAAUW,EAAMC,EAAaA,EAAc3F,GAC5D6F,EAAa,GAAIC,YACjBC,EAAU,GAAI9L,IAAG+L,OAUrB,OARAH,GAAWI,OAAS,WAChBF,EAAQG,QAAQjM,GAAGmL,iBAAiBS,EAAWjJ,UAGnDiJ,EAAWM,QAAUJ,EAAQK,QAE7BP,EAAWQ,kBAAkBT,GAEtBG,GAGX9L,GAAG6B,OAAS,SAASY,EAAO4J,EAAQC,GAahC,MAZAtM,IAAG+C,KAAKsJ,EAAQ,SAASE,EAAMtJ,GACvBqJ,GAAgBtM,GAAGuG,SAAStD,IACRkB,SAAhB1B,EAAM8J,KACN9J,EAAM8J,OAEVvM,GAAG6B,OAAOY,EAAM8J,GAAOtJ,GAAK,IAG5BR,EAAM8J,GAAQtJ,IAIfR,GAaXzC,GAAGwM,SAAW,SAASC,EAAQC,GAC3B,GAAIC,MACAC,EAASF,EAASC,EAUtB,OARA3M,IAAG+C,KAAK6J,EAAQ,SAASC,EAAaC,GACN3I,SAAxBsI,EAAOI,KACPF,EAAOE,GAAeJ,EAAOI,IAGjCJ,EAAOI,GAAeC,IAGnBL,GAMXzM,GAAG2F,QAAU,SAASoH,EAAKC,EAAKC,GAC5B,GAAIF,EAAIpH,QACJ,MAAOoH,GAAIpH,QAAQqH,EAAKC,EAG5BA,GAAOA,GAAQ,CACf,IAAIC,GAAMH,EAAIhH,MAMd,KAJIkH,EAAO,IACPA,GAAQC,GAGLD,EAAOC,EAAKD,GAAQ,EACvB,GAAIF,EAAII,eAAeF,IAASF,EAAIE,KAAUD,EAC1C,MAAOC,EAGf,QAAO,GAIXjN,GAAGoN,YAAc,WACb,MAAO,uCAAuC7K,QAAQ,QAAS,SAAS8K,GAEpE,GAAIC,GAAoB,GAAhB3L,KAAK4L,SAAgB,EAAGC,EAAS,KAALH,EAAWC,EAAS,EAAJA,EAAU,CAC9D,OAAOE,GAAE7G,SAAS,OAM1B3G,GAAGyN,GAAK,WACJ,MAAOC,WAAUC,UAAUhI,QAAQ,WAAY,GAC3C+H,UAAUC,UAAUhI,QAAQ,cAAe,GAGnD3F,GAAG4N,IAAM,WACL,MAAOF,WAAUC,UAAUhI,QAAQ,aAAc,GAGrD3F,GAAG6N,IAAM,WACL,MAAOH,WAAUC,UAAUhI,QAAQ,aAAc,GAGrD3F,GAAG8N,KAAO,WACN,MAAOJ,WAAUC,UAAUhI,QAAQ,cAAe,GAGtD3F,GAAG+N,KAAO,WACN,MAAO/N,IAAGyN,MAAQC,UAAUC,UAAUhI,QAAQ,YAAa,GAG/D3F,GAAGgO,KAAO,WACN,MAAON,WAAUC,UAAUhI,QAAQ,SAAW,GAGlD3F,GAAGiO,OAAS,WACR,MAA4B9J,UAArBuJ,UAAUQ,QAAwBR,UAAUQ,OAAOvI,QAAQ,YAAa,GAGnF3F,GAAGmO,OAAS,WACR,MAA4BhK,UAArBuJ,UAAUQ,QAAwBR,UAAUQ,OAAOvI,QAAQ,aAAc,GAGpF3F,GAAGoO,MAAQ,WACP,MAA4BjK,UAArBuJ,UAAUQ,QAAwBR,UAAUQ,OAAOvI,QAAQ,YAAa,GAGnF3F,GAAGqO,QAAU,WACT,OAASrO,GAAGgO,SAAWhO,GAAG+N,QAAUL,UAAUC,UAAUhI,QAAQ,cAAe,GAA2BxB,SAArBuJ,UAAUQ,QAA6C,KAArBR,UAAUQ,QAGrIlO,GAAGsO,QAAU,WACT,MAA8B,UAAvBZ,UAAUa,UAGrBvO,GAAGwO,QAAU,WACT,MAAOd,WAAUC,UAAUrE,cAAc3D,QAAQ,cAAe,GAKpE3F,GAAG2K,aAAe,WACd,MAAO3K,IAAGwO,WAAad,UAAUC,UAAUrE,cAAc3D,QAAQ,UAAY,GAGjF3F,GAAGyO,KAAO,WACN,MAAOzO,IAAG0O,OAAShB,UAAUC,UAAUhI,QAAQ,aAAc,GAGjE3F,GAAG2O,KAAO,WACN,MAAO3O,IAAG0O,OAAShB,UAAUC,UAAUhI,QAAQ,aAAc,GAGjE3F,GAAG4O,KAAO,WACN,MAAO5O,IAAG0O,OAAShB,UAAUC,UAAUhI,QAAQ,aAAc,GAIjE3F,GAAG6O,OAAS,WACR,MAAO7O,IAAG0O,OAAShB,UAAUC,UAAUhI,QAAQ,eAAgB,GAGnE3F,GAAG0O,IAAM,WAEL,MAAOhB,WAAUC,UAAUhI,QAAQ,WAAY,GACxC+H,UAAUC,UAAUhI,QAAQ,WAAY,GACxC+H,UAAUC,UAAUhI,QAAQ,aAAc,GAGrD3F,GAAG8O,UAAY,WACX,MAAO9O,IAAG0O,OAAShB,UAAUC,UAAUhI,QAAQ,YAAa,GAGhE3F,GAAG+O,UAAY,WACX,MAAO/O,IAAG0O,QAAU1O,GAAG8O,aAAepB,UAAUC,UAAUhI,QAAQ,aAAc,GAGpF3F,GAAGgP,iBAAmB,WAClB,MAAOhP,IAAG0O,QAAU1O,GAAG8O,cAAgB9O,GAAG+O,aAM9C/O,GAAGiP,eAAiB,SAASC,GACrBA,EAAED,eACFC,EAAED,iBAEFC,EAAEC,aAAc,GAQxBnP,GAAGoP,UAAa,WACZ,GAAIC,GAAMxF,SAASC,cAAc,MACjC,OAAO,UAASwF,GACZD,EAAIE,UAAYD,CAChB,IAAIrP,GAAUoP,EAAI/L,UAElB,OADA+L,GAAIhO,YAAYpB,GACTA,MAKfD,GAAG+C,KAAO,SAASyM,EAAcC,GAC7B,GAAIC,GAAYC,CAEhB,IAAIH,EAEA,GAAItK,OAAO0K,SAAWJ,EAAavI,cAAgB/B,OAAO0K,QACtD,IAAKF,EAAa,EAAGA,EAAaF,EAAazJ,SAC3C4J,EAASF,EAASD,EAAaK,IAAIH,GAAaF,EAAaM,QAAQN,EAAaK,IAAIH,KAClFC,KAAW,GAFoCD,SAStD,IAAI1P,GAAG8G,QAAQ0I,IAAiBxP,GAAGkH,WAAWsI,IAAiBxP,GAAGoH,WAAWoI,GAC9E,IAAKE,EAAa,EAAGA,EAAaF,EAAazJ,SAC3C4J,EAASF,EAASC,EAAYF,EAAaE,IACvCC,KAAW,GAFoCD,SAOtD,IAAI1P,GAAGwH,SAASgI,GACjB,IAAKE,EAAa,EAAGA,EAAaF,EAAazJ,SAC3C4J,EAASF,EAASC,EAAYF,EAAaO,OAAOL,IAC9CC,KAAW,GAFoCD,SAQvD,KAAKA,IAAcF,GACf,GAAI/I,OAAOC,UAAUyG,eAAevG,KAAK4I,EAAcE,KACnDC,EAASF,EAASC,EAAYF,EAAaE,IACvCC,KAAW,GACX,OASxB3P,GAAGgQ,KAAO,SAASC,EAASC,GACxB,GAAIlQ,GAAG6G,WAAWoJ,GAAU,CACxB,GAAIjI,GAAQC,MAAMvB,UAAUwB,MAAMtB,KAAKuB,UAAW,EAElD,OAAO,YACH,GAAIgI,GAAUnQ,GAAG6B,UAAWmG,EAI5B,OAHIG,WAAUpC,SACVoK,EAAUA,EAAQC,OAAOnI,MAAMvB,UAAUwB,MAAMtB,KAAKuB,aAEjD8H,EAAQI,MAAMH,EAASC,IAItC,KAAM,IAAI3O,OAAM,wCAmBpBxB,GAAGsQ,QAAU,SAASC,EAAKC,EAAMC,GAE7B,GAAIC,MACAC,EAAS,IACTC,EAAM,SAASC,EAASC,GACpB,GAAIC,GAAWP,EACR,QAAQrO,KAAKqO,GACdA,EACAA,EAAO,IAAMM,EAAI,IACjBA,CACY,eAAbC,GAAoC,cAAND,GAC/BJ,EAAWxN,KACa,gBAAZ2N,GACF7Q,GAAGsQ,QAAQO,EAASE,GAAU,GACe,sBAA5CtK,OAAOC,UAAUC,SAASC,KAAKiK,GAChCG,mBAAmBD,GAAY,IAAMC,mBAAmBH,KACxDG,mBAAmBD,GAAY,IAAMC,mBAAmBH,IAqB9E,QAhBKJ,GAAcD,GACfG,EAAU,KAAKxO,KAAKqO,GAAU,MAAMrO,KAAKqO,GAAS,GAAK,IAAM,IAC7DE,EAAWxN,KAAKsN,GAChBE,EAAWxN,KAAKlD,GAAGsQ,QAAQC,KACqB,mBAAxC9J,OAAOC,UAAUC,SAASC,KAAK2J,IAA8C,mBAARA,GAC7EvQ,GAAG+C,KAAKwN,EAAK,SAASvN,EAAKC,GACvB2N,EAAI3N,EAAKD,KAEU,mBAARuN,IAAiC,OAARA,GAAiC,gBAARA,GACjEvQ,GAAG+C,KAAKwN,EAAK,SAAShE,EAAMtJ,GACxB2N,EAAI3N,EAAKsJ,KAGbmE,EAAWxN,KAAK8N,mBAAmBR,GAAQ,IAAMQ,mBAAmBT,IAGpEC,EACOE,EAAWO,KAAKN,GAEhBD,EAAWO,KAAKN,GAClBpO,QAAQ,KAAM,IACdA,QAAQ,OAAQ,MAI7BvC,GAAGkR,aAAe,SAASX,EAAKY,EAAUC,GAmBtC,MAlBKD,KACDA,EAAW,GAAInH,WAGnBhK,GAAG+C,KAAKwN,EAAK,SAASV,EAAK5M,GACvB4M,EAAMuB,EAAeA,EAAe,IAAMvB,EAAM,IAAMA,EAElD7P,GAAGuG,SAAStD,GACZjD,GAAGkR,aAAajO,EAAKkO,EAAUtB,GAE1B7P,GAAG6G,WAAW5D,GACnBkO,EAAS5L,OAAOsK,EAAK5M,KAGrBkO,EAAS5L,OAAOsK,EAAK5M,KAItBkO,GAGXnR,GAAGqR,WAAa,SAASd,EAAKe,GAC1B,GAAI1H,EAeJ,OAbK0H,KACDA,EAAOzH,SAASC,cAAc,SAGlC9J,GAAGkR,aAAaX,GACZhL,OAAQ,SAASsK,EAAK5M,GAClB2G,EAAQC,SAASC,cAAc,SAC/BF,EAAM2H,aAAa,OAAQ1B,GAC3BjG,EAAM2H,aAAa,QAAStO,GAC5BqO,EAAKE,YAAY5H,MAIlB0H,GAOXtR,GAAGyR,UAAY,SAASC,MAEpB,MAAIxM,QAAOyM,MAAQ3R,GAAG6G,WAAW8K,KAAKC,OAC3BD,KAAKC,MAAMF,MAEXG,KAAK,IAAMH,KAAO,MAUjC1R,GAAG8R,aAAe,SAASC,GACvB,GAAIC,GAASD,EAASE,YAAY,KAAO,CAEzC,IAAID,EAAS,EACT,MAAOD,GAASG,OAAOF,EAAQD,EAAShM,OAASiM,IAIzDhS,GAAGmS,YAAc,SAASC,GAGtB,MAAIpS,IAAGiJ,QAAQmJ,GAEJA,EAAgBrL,MAAMxE,QAAQ,YAAa,IAE7CvC,GAAGyI,OAAO2J,IACkB,OAA7BA,EAAgBC,UAAkDlO,SAA7BiO,EAAgBC,SAC9CD,EAAgBC,SAIxBD,EAAgBrQ,MAM3B/B,GAAGsS,eAAiB,WAChB,GAAIC,KAEJ,QAEIC,QAAS,WACL,GAAIC,EACJ,GACIA,GAAWF,EAAUG,QACjBD,GACAA,UAGDA,IAIXnS,OAAQ,WACJ,GAAI0H,GAAOG,SAEX9H,MAAKsS,YAAY3S,GAAGgI,EAAK,IAAI1H,OAAO+P,MAAMhQ,KAAM4H,MAAMvB,UAAUwB,MAAMtB,KAAKuB,UAAW,MAI1FwK,YAAa,SAASC,GAClBL,EAAUrP,KAAK0P,SCt2B9B,WACG,YACsB,mBAAXC,SAAyBA,OAAOC,IACvCD,OAAO,WACH,MAAO7S,MAGY,mBAAX+S,SAA0BA,OAAOC,QAC7CD,OAAOC,QAAUhT,GAGjBD,OAAOC,GAAKA,MCXpBA,GAAGiT,QAAU,SCAbjT,GAAGkT,kBAAqB,WACpB,YAkBA,SAASC,KACL,GACIC,GADAC,GAAY,CAGhB,KACID,EAAYvJ,SAASC,cAAc,SACnCsJ,EAAU7S,KAAO,OACjBP,GAAGoT,GAAWlT,OAEVkT,EAAUE,WACVD,GAAY,GAGpB,MAAOE,GACHF,GAAY,EAGhB,MAAOA,GAIX,QAASG,KACL,OAAQxT,GAAGmO,UAAYnO,GAAGoO,UAC+CjK,SAArEuJ,UAAUC,UAAU8F,MAAM,uCAIlC,QAASC,KACL,OAAQ1T,GAAGmO,UAAYnO,GAAGoO,UAC+CjK,SAArEuJ,UAAUC,UAAU8F,MAAM,uCAIlC,QAASE,KACL,GAAIzO,OAAOiF,eAAgB,CACvB,GAAIyJ,GAAM5T,GAAGiK,mBAGb,OAA+B9F,UAAxByP,EAAIC,gBAGf,OAAO,EAIX,QAASC,KACL,MAAiC3P,UAA1Be,OAAO6O,eAKlB,QAASC,KACL,QAAIL,KAIGG,IAGX,QAASG,KAEL,MAA2D9P,UAApD0F,SAASC,cAAc,SAASoK,gBAG3C,QAASC,KACL,IACI,QAASjP,OAAOkP,cAEZpU,GAAG6G,WAAW3B,OAAOkP,aAAaC,SAE1C,MAAOhK,GAEH,OAAO,GAIf,QAASiK,KACL,GAAIC,GAAO1K,SAASC,cAAc,OAElC,QAAQ,aAAeyK,IAAS,eAAiBA,IAAQ,UAAYA,MAChEvU,GAAGwO,YAAcxO,GAAG0O,MAhG7B,GAAI8F,GACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,CAwHJ,OAnCAd,GAAoBrB,IAEpBwB,EAA4BH,GAAqBxU,GAAG2J,uBAEpD8K,EAAyBE,IAA8B3U,GAAG2K,eAE1D+J,EAAmBC,GAA6BL,IAEhDM,EAAqBF,GAAoBlB,IAEzCqB,EAAmBF,GAA6B3U,GAAG0K,0BAEnDoK,EAAiBH,GAA6BE,GAAoBV,IAElEY,EAAyBJ,GAA6BjB,IAEtDsB,EAAqBR,IAA6CrQ,SAAvBe,OAAOqQ,aAA6BZ,GAE/EO,EAA4BvB,IAE5BsB,EAAwBnB,IAExBqB,EAAyBnB,IAEzBoB,EAA0BnB,IAE1BoB,EAAwBV,GAAmDxQ,SAAtBe,OAAO2G,WAE5DyJ,EAA0B,WACtB,QAAIX,KACQ3U,GAAG2K,iBAAmB3K,GAAG8O,iBAMrC0G,cAAeb,EACfc,cAAehB,EACfiB,iBAAkBf,EAClBgB,SAAUd,EACVe,eAAgBT,EAChBU,kBAAmBZ,EACnBa,kBAAmBZ,EACnBa,gBAAiB7Q,OAAO8Q,kBACxBC,SAAUvB,EACVwB,WAAYtB,EACZuB,gBAAiBf,EACjBgB,cAAef,EACfgB,gBAAiBhB,EACjBiB,mBAAoB3B,EACpB4B,MAAO1B,EACP2B,YAAalB,EACbmB,OAAQ3B,EACR4B,QAASrB,GAAyBZ,EAClCkC,aAAc3W,GAAGiO,SACjB2I,0BAA2B5W,GAAG0O,MAC9BmI,UAAWrC,EACXsC,WAAY9B,EACZ+B,oBAAqBpC,EACrBqC,mBAAoBrC,EACpBsC,eAAgBlC,MChKxB/U,GAAGkX,iBAAmB,SAASC,GAC3B,YACA,UAAUA,GAAgBA,EAAaC,MAAQpX,GAAG6G,WAAWsQ,EAAaC,QAG9EpX,GAAG+L,QAAU,WACT,YAEA,IAAIsL,GAAaC,EACbC,KACAC,KACAC,KACAC,EAAQ,CAEZ1X,IAAG6B,OAAOxB,MACN+W,KAAM,SAASO,EAAWC,GAgBtB,MAfc,KAAVF,GACIC,GACAJ,EAAiBrU,KAAKyU,GAEtBC,GACAJ,EAAiBtU,KAAK0U,IAGrBF,KAAU,EACfE,GAAaA,EAAUvH,MAAM,KAAMiH,GAE9BK,GACLA,EAAUtH,MAAM,KAAMgH,GAGnBhX,MAGXwX,KAAM,SAASpI,GAQX,MAPc,KAAViI,EACAD,EAAcvU,KAAKuM,GAGnBA,EAASY,MAAM,KAAsBlM,SAAhBmT,EAA4BD,EAAcC,GAG5DjX,MAGX4L,QAAS,WAgBL,MAfAyL,GAAQ,EACRL,EAAclP,UAEVoP,EAAiBxR,QACjB/F,GAAG+C,KAAKwU,EAAkB,SAASvU,EAAKyM,GACpCA,EAASY,MAAM,KAAMgH,KAIzBI,EAAc1R,QACd/F,GAAG+C,KAAK0U,EAAe,SAASzU,EAAKyM,GACjCA,EAASY,MAAM,KAAMgH,KAItBhX,MAGX8L,QAAS,WAgBL,MAfAuL,IAAQ,EACRJ,EAAcnP,UAEVqP,EAAiBzR,QACjB/F,GAAG+C,KAAKyU,EAAkB,SAASxU,EAAKyM,GACpCA,EAASY,MAAM,KAAMiH,KAIzBG,EAAc1R,QACd/F,GAAG+C,KAAK0U,EAAe,SAASzU,EAAKyM,GACjCA,EAASY,MAAM,KAAMiH,KAItBjX,SClFnBL,GAAG8X,YAAc,SAASC,GACtB,YAoBA,SAASC,GAAmBC,EAAOC,GAE/B,GAAIC,GAAelQ,MAAMvB,UAAUwB,MAAMtB,KAAKqR,EAE9CG,GAAQC,UAAUC,QAAQ,WAAaL,EAAMlS,OAAS,mBACtDmS,EAAeK,cAAa,GAC5BH,EAAQC,UAAUG,+BAA+BL,EAAcD,EAAeO,cAGlF,QAASC,GAAiBC,GACtB,GAAIC,GAAoB,GAAI5Y,IAAG+L,OAoD/B,OAlDI4M,GAAMlQ,OACNkQ,EAAME,KAAK,SAASA,GAChB,GAAI9W,GAAO4W,EAAM5W,KACb+W,EAAWH,EAAMG,SACjBC,EAAwBD,EAASnT,QAAQ5D,EAG7C+W,GAAWA,EAAS5G,OAAO,EAAG6G,GAGH,MAAvBD,EAAS/I,OAAO,KAChB+I,EAAWA,EAAS5G,OAAO,IAG/B2G,EAAKG,OAASF,EACdG,EAAa/V,KAAK2V,GAClBD,EAAkB3M,WAEtB,SAASiN,GACLd,EAAQC,UAAUC,QAAQ,oBAAsBK,EAAMG,SAAW,sBAAwBI,EAAUC,KAAO,IAAK,SAC/GP,EAAkBzM,YAGjBwM,EAAMS,aACXC,EAAoBV,GAAOvB,KACvB,SAAwBkC,GACpB,GAAIC,GAAcD,EAAQvT,MAE1B/F,IAAG+C,KAAKuW,EAAS,SAAStW,EAAK2V,GAC3BD,EAAiBC,GAAOd,KAAK,WACzB0B,GAAe,EAEK,IAAhBA,GACAX,EAAkB3M,cAKzBqN,EAAQvT,QACT6S,EAAkB3M,WAI1B,SAAqBiN,GACjBd,EAAQC,UAAUC,QAAQ,oBAAsBK,EAAMG,SAAW,sBAAwBI,EAAUC,KAAO,IAAK,SAC/GP,EAAkBzM,YAKvByM,EAIX,QAASS,GAAoBV,EAAOa,EAAQC,EAAcC,GACtD,GAAI5N,GAAU4N,GAAmB,GAAI1Z,IAAG+L,QACpC4N,EAAYH,GAAUb,EAAMiB,cAmBhC,OAjBAD,GAAUE,YACN,SAAqBP,GACjB,GAAIQ,GAAaL,EAAeA,EAAarJ,OAAOkJ,GAAWA,CAE3DA,GAAQvT,OACRgU,WAAW,WACPV,EAAoBV,EAAOgB,EAAWG,EAAYhO,IACnD,GAGHA,EAAQG,QAAQ6N,IAIxBhO,EAAQK,SAGLL,EAGX,QAASkO,GAAmBzP,EAAc2N,GACtC,GAAI+B,MACAC,EAA4B,GAAIla,IAAG+L,OA4CvC,OA1CAqM,GAAQC,UAAU8B,yBAClBjC,EAAeK,cAAa,GAExBhO,EAAa0N,MAAMlS,OAAS,IAAMqS,EAAQgC,oBAC1ChC,EAAQC,UAAUG,mCAClBJ,EAAQC,UAAUgC,UAAU,oBAAqB,IACjDnC,EAAeK,cAAa,GAC5B2B,EAA0B/N,YAG1B8M,KAEIjZ,GAAGsK,sBAAsBC,GACzBvK,GAAG+C,KAAKwH,EAAaC,MAAO,SAASxH,EAAKsE,GACtC,GAAIqR,GAAQrR,EAAKmD,kBAEbkO,KAEIA,EAAMlQ,OACNwQ,EAAa/V,KAAKoE,EAAKgT,aAIvBL,EAAsB/W,KAAKwV,EAAiBC,GAAOd,KAAK,WACpDoC,EAAsBM,MACe,IAAjCN,EAAsBlU,QACtBmU,EAA0BjO,gBAQ9CgN,EAAe1O,EAAa0N,MAGK,IAAjCgC,EAAsBlU,QACtBmU,EAA0BjO,WAI3BiO,EAGX,QAASM,GAAcC,GACnB,GAAIC,GAAW,GAAI1a,IAAG2a,gBAClBC,sBAAuBA,EACvB3a,QAASwa,EACTI,QAAS,SAAS3L,GACdlP,GAAGya,GAAUpY,SAAS+V,EAAQ0C,QAAQC,YACtC7L,EAAE8L,mBAENC,sBAAuB,SAAS/L,GAC5BlP,GAAGya,GAAUnY,YAAY8V,EAAQ0C,QAAQC,aAE7CG,OAAQ,SAAShM,GACb8K,EAAmB9K,EAAE3E,aAAcmQ,GAAUtD,KACzC,WACIY,EAAmBiB,EAAcyB,IAErC,WACItC,EAAQC,UAAUC,QAAQ,sEAAuE,aAcjH,OARA6C,GAAexI,YAAY,WACvB+H,EAASlI,YAGbxS,GAAGya,GAAU3W,aAAasX,IAA2Bpb,GAAGya,GAAUva,OAElEmb,EAAgBnY,KAAKwX,GAEdA,EAGX,QAASY,GAAWC,GAChB,GAAIC,EASJ,OAPAxb,IAAG+C,KAAKwY,EAAUhR,aAAakR,MAAO,SAAS5L,EAAK5M,GAChD,GAAY,UAARA,EAEA,MADAuY,IAAW,GACJ,IAIRA,EAWX,QAASE,GAAmBxM,GACxB,MAAIlP,IAAGqO,WACKa,EAAEyM,cAGV3b,GAAGiO,SACIiB,EAAE0M,EAAI,GAAK1M,EAAE2M,EAAI,EAGb,IAAR3M,EAAE0M,GAAmB,IAAR1M,EAAE2M,EAG1B,QAASC,KACL,GAAIC,GAAY3D,EAAQ4D,iBAEpBC,EAAqB,WACjBlC,WAAW,WACP/Z,GAAG+C,KAAKgZ,EAAW,SAAS/Y,EAAK0X,GAC7B1a,GAAG0a,GAAU5W,aAAasX,IAA2Bpb,GAAG0a,GAAUxa,OAClEF,GAAG0a,GAAUpY,YAAY8V,EAAQ0C,QAAQC,eAE9C,IAGX/a,IAAG+C,KAAKgZ,EAAW,SAAS/Y,EAAK0X,GAC7B,GAAIxC,GAAiBsC,EAAcE,EAG/BqB,GAAUhW,QAAU/F,GAAGkT,kBAAkB+C,UACzCkF,EAAe7a,OAAOuJ,SAAU,YAAa,SAASqF,IAC7CgJ,EAAeK,gBAAkB+C,EAAWpM,IAC7ClP,GAAG+C,KAAKgZ,EAAW,SAAS/Y,EAAK0X,GAGzBA,YAAoBwB,cACpBlc,GAAG0a,GAAU5W,aAAasX,IAE1Bpb,GAAG0a,GAAUpZ,KAAKlB,QAAS,gBAQnD+a,EAAe7a,OAAOuJ,SAAU,YAAa,SAASqF,GAC9CwM,EAAmBxM,IACnB+M,MAORd,EAAe7a,OAAON,GAAG6J,UAAUzG,WAAW,GAAI,aAAc,SAAS8L,GACrE+M,MAGJd,EAAe7a,OAAOuJ,SAAU,OAAQ,SAASqF,GAC7CA,EAAED,iBACFgN,MAGJd,EAAe7a,OAAOuJ,SAAU+Q,EAAuBqB,GAnR3D,GAAI7D,GACAwC,EAAwB,eACxBQ,EAAyB,mBACzBC,KACApC,KACAkC,EAAiB,GAAInb,IAAGsS,cAE5B8F,IACI4D,oBACA5B,oBAAoB,EACpBU,SACIC,WAAY,MAEhB1C,UAAW,GAAIrY,IAAG8X,YAAYO,WAGlCrY,GAAG6B,OAAOuW,EAASL,GAAG,GAsQtB+D,IAEA9b,GAAG6B,OAAOxB,MACN8b,mBAAoB,SAASlc,GACzBmY,EAAQ4D,iBAAiB9Y,KAAKjD,GAC9Bua,EAAcva,IAGlBmc,eAAgB,SAASnc,GACrB,GAAI6Q,GACAuL,EAAMjE,EAAQ4D,gBAElB,KAAKlL,IAAKuL,GACN,GAAIA,EAAIvL,KAAO7Q,EACX,MAAOoc,GAAIC,OAAOxL,EAAG,IAKjC0B,QAAS,WACL2I,EAAe3I,UACfxS,GAAG+C,KAAKsY,EAAiB,SAASrY,EAAK0X,GACnCA,EAASlI,gBAMzBxS,GAAG8X,YAAYO,UAAY,WACvB,YAEA,QACI8B,uBAAwB,aACxB3B,+BAAgC,SAASP,EAAOsE,KAChDlC,UAAW,SAASlB,EAAMqD,GACtBxc,GAAGmG,IAAI,2BAA6BgT,EAAO,2BAA6BqD,EAAiB,IAAK,UAElGlE,QAAS,SAASlS,EAASC,GACvBrG,GAAGmG,IAAIC,EAASC,MAK5BrG,GAAG2a,eAAiB,SAAS5C,GACzB,YAiBA,SAAS0E,KACL,MAAOzc,IAAGiO,UAAajO,GAAGqO,WAAarO,GAAGsO,UAG9C,QAASoO,GAAmBxN,GAEnByN,IAGGF,EACAtB,EAAe7a,OAAOuJ,SAAU,WAAY,SAASqF,GACjDA,EAAED,mBAGNkM,EAAe7a,OAAOuJ,SAAU,WAAY,SAASqF,GAC7CA,EAAE3E,eACF2E,EAAE3E,aAAaqS,WAAa,OAC5B1N,EAAED,oBAKd0N,GAAsB,GAI9B,QAASE,GAAgB3N,GAGrB,IAAKlP,GAAGkT,kBAAkB+C,SACtB,OAAO,CAGX,IAAI6G,GAAYC,EAAK7N,EAAE3E,aAEvByS,EAAWhd,GAAGiO,QAQd,OADA6O,MAAa9c,GAAGyN,OAAQzN,GAAGkT,kBAAkB+C,WAAuC,SAArB8G,EAAGE,cAC3DF,GAAMD,IAAeC,EAAG9E,QAAW+E,GAAYD,EAAGtB,MAAM3a,UAAYic,EAAGtB,MAAM3a,SAAS,UAGjG,QAASoc,GAAoBC,GAIzB,MAHmBhZ,UAAfgZ,IACAC,EAAcD,GAEXC,EAGX,QAASC,KAGL,QAASC,KACLC,EAAiB1T,SAAS2T,YAAY,SACtCD,EAAeE,UAAUrF,EAAQwC,uBAAuB,GAAM,GAJlE,GAAI2C,EAOJ,IAAIrY,OAAOwY,YACP,IACIH,EAAiB,GAAIG,aAAYtF,EAAQwC,uBAE7C,MAAO+C,GACHL,QAIJA,IAGJzT,UAAS+T,cAAcL,GAG3B,QAASM,KACL1C,EAAe7a,OAAOL,EAAS,WAAY,SAASiP,GAChD,GAAK2N,EAAgB3N,GAArB,CAMA,GAAI4O,GAAS9d,GAAGyN,MAAQzN,GAAGkT,kBAAkB+C,SAAW,KAAO/G,EAAE3E,aAAa0S,aAC/D,UAAXa,GAAgC,aAAXA,EACrB5O,EAAE3E,aAAaqS,WAAa,OAE5B1N,EAAE3E,aAAaqS,WAAa,OAGhC1N,EAAE8L,kBACF9L,EAAED,oBAGNkM,EAAe7a,OAAOL,EAAS,YAAa,SAASiP,GACjD,IAAKgO,IAAuB,CACxB,IAAKL,EAAgB3N,GACjB,MAEJkJ,GAAQyC,QAAQ3L,MAIxBiM,EAAe7a,OAAOL,EAAS,YAAa,SAASiP,GACjD,GAAK2N,EAAgB3N,GAArB,CAIAkJ,EAAQ2F,QAAQ7O,EAEhB,IAAIyM,GAAgB9R,SAASmU,iBAAiB9O,EAAE+O,QAAS/O,EAAEgP,QAEvDle,IAAGK,MAAMS,SAAS6a,IAItBvD,EAAQ6C,sBAAsB/L,MAGlCiM,EAAe7a,OAAOL,EAAS,OAAQ,SAASiP,GAC5C,IAAKgO,IAAuB,CACxB,IAAKL,EAAgB3N,GACjB,MAGJA,GAAED,iBACFC,EAAE8L,kBACF5C,EAAQ8C,OAAOhM,GAEfmO,OAjJZ,GACIjF,GAASnY,EAASmd,EAAaT,EAD/BxB,EAAiB,GAAInb,IAAGsS,cAG5B8F,IACInY,QAAS,KACT4a,QAAS,SAAS3L,KAClB6O,QAAS,SAAS7O,KAElB+L,sBAAuB,SAAS/L,KAChCgM,OAAQ,SAAShM,MAGrBlP,GAAG6B,OAAOuW,EAASL,GACnB9X,EAAUmY,EAAQnY,QAyIlByc,IACAmB,IAEA7d,GAAG6B,OAAOxB,MACNkY,aAAc,SAAS4E,GACnB,MAAOD,GAAoBC,IAG/B3K,QAAS,WACL2I,EAAe3I,WAGnBiG,WAAY,WACR,MAAOxY,QN3eYiF","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("