addressbook.php 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. <?php
  2. /**
  3. * ownCloud - Addressbook
  4. *
  5. * @author Jakob Sack
  6. * @copyright 2011 Jakob Sack mail@jakobsack.de
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
  10. * License as published by the Free Software Foundation; either
  11. * version 3 of the License, or any later version.
  12. *
  13. * This library is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
  17. *
  18. * You should have received a copy of the GNU Affero General Public
  19. * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  20. *
  21. */
  22. /*
  23. *
  24. * The following SQL statement is just a help for developers and will not be
  25. * executed!
  26. *
  27. * CREATE TABLE contacts_addressbooks (
  28. * id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
  29. * userid VARCHAR(255) NOT NULL,
  30. * displayname VARCHAR(255),
  31. * uri VARCHAR(100),
  32. * description TEXT,
  33. * ctag INT(11) UNSIGNED NOT NULL DEFAULT '1'
  34. * );
  35. *
  36. */
  37. /**
  38. * This class manages our addressbooks.
  39. */
  40. class OC_Contacts_Addressbook{
  41. /**
  42. * @brief Returns the list of addressbooks for a specific user.
  43. * @param string $uid
  44. * @return array
  45. */
  46. public static function all($uid){
  47. $stmt = OCP\DB::prepare( 'SELECT * FROM `*PREFIX*contacts_addressbooks` WHERE `userid` = ? ORDER BY `displayname`' );
  48. $result = $stmt->execute(array($uid));
  49. $addressbooks = array();
  50. while( $row = $result->fetchRow()){
  51. $addressbooks[] = $row;
  52. }
  53. return $addressbooks;
  54. }
  55. /**
  56. * @brief Returns the list of addressbooks for a principal (DAV term of user)
  57. * @param string $principaluri
  58. * @return array
  59. */
  60. public static function allWherePrincipalURIIs($principaluri){
  61. $uid = self::extractUserID($principaluri);
  62. return self::all($uid);
  63. }
  64. /**
  65. * @brief Gets the data of one address book
  66. * @param integer $id
  67. * @return associative array
  68. */
  69. public static function find($id){
  70. try {
  71. $stmt = OCP\DB::prepare( 'SELECT * FROM `*PREFIX*contacts_addressbooks` WHERE `id` = ?' );
  72. $result = $stmt->execute(array($id));
  73. return $result->fetchRow();
  74. } catch(Exception $e) {
  75. OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(), OCP\Util::ERROR);
  76. OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', id: '.$id, OCP\Util::DEBUG);
  77. return false;
  78. }
  79. }
  80. /**
  81. * @brief Creates a new address book
  82. * @param string $userid
  83. * @param string $name
  84. * @param string $description
  85. * @return insertid
  86. */
  87. public static function add($userid,$name,$description=''){
  88. $all = self::all($userid);
  89. $uris = array();
  90. foreach($all as $i){
  91. $uris[] = $i['uri'];
  92. }
  93. $uri = self::createURI($name, $uris );
  94. $stmt = OCP\DB::prepare( 'INSERT INTO `*PREFIX*contacts_addressbooks` (`userid`,`displayname`,`uri`,`description`,`ctag`) VALUES(?,?,?,?,?)' );
  95. $result = $stmt->execute(array($userid,$name,$uri,$description,1));
  96. return OCP\DB::insertid('*PREFIX*contacts_addressbooks');
  97. }
  98. /**
  99. * @brief Creates a new address book from the data sabredav provides
  100. * @param string $principaluri
  101. * @param string $uri
  102. * @param string $name
  103. * @param string $description
  104. * @return insertid
  105. */
  106. public static function addFromDAVData($principaluri,$uri,$name,$description){
  107. $userid = self::extractUserID($principaluri);
  108. $stmt = OCP\DB::prepare( 'INSERT INTO `*PREFIX*contacts_addressbooks` (`userid`,`displayname`,`uri`,`description`,`ctag`) VALUES(?,?,?,?,?)' );
  109. $result = $stmt->execute(array($userid,$name,$uri,$description,1));
  110. return OCP\DB::insertid('*PREFIX*contacts_addressbooks');
  111. }
  112. /**
  113. * @brief Edits an addressbook
  114. * @param integer $id
  115. * @param string $name
  116. * @param string $description
  117. * @return boolean
  118. */
  119. public static function edit($id,$name,$description){
  120. // Need these ones for checking uri
  121. $addressbook = self::find($id);
  122. if(is_null($name)){
  123. $name = $addressbook['name'];
  124. }
  125. if(is_null($description)){
  126. $description = $addressbook['description'];
  127. }
  128. $stmt = OCP\DB::prepare( 'UPDATE `*PREFIX*contacts_addressbooks` SET `displayname`=?,`description`=?, `ctag`=`ctag`+1 WHERE `id`=?' );
  129. $result = $stmt->execute(array($name,$description,$id));
  130. return true;
  131. }
  132. public static function cleanArray($array, $remove_null_number = true){
  133. $new_array = array();
  134. $null_exceptions = array();
  135. foreach ($array as $key => $value){
  136. $value = trim($value);
  137. if($remove_null_number){
  138. $null_exceptions[] = '0';
  139. }
  140. if(!in_array($value, $null_exceptions) && $value != "") {
  141. $new_array[] = $value;
  142. }
  143. }
  144. return $new_array;
  145. }
  146. /**
  147. * @brief Get active addressbooks for a user.
  148. * @param integer $uid User id. If null current user will be used.
  149. * @return array
  150. */
  151. public static function activeIds($uid = null){
  152. if(is_null($uid)){
  153. $uid = OCP\USER::getUser();
  154. }
  155. $prefbooks = OCP\Config::getUserValue($uid,'contacts','openaddressbooks',null);
  156. $prefbooks = explode(';',$prefbooks);
  157. for ($i = 0; $i < count($prefbooks); $i++) {
  158. if(!$prefbooks[$i] || !self::find($prefbooks[$i])) {
  159. unset($prefbooks[$i]);
  160. }
  161. }
  162. if(!$prefbooks){
  163. OCP\Util::writeLog('contacts','OC_Contacts_Addressbook:activeIds:, No active addressbooks',OCP\Util::DEBUG);
  164. $addressbooks = OC_Contacts_Addressbook::all($uid);
  165. if(count($addressbooks) == 0){
  166. OCP\Util::writeLog('contacts','OC_Contacts_Addressbook:activeIds:, No addressbooks',OCP\Util::DEBUG);
  167. $id = self::add($uid,'default','Default Address Book');
  168. OCP\Util::writeLog('contacts','OC_Contacts_Addressbook:activeIds:, Created addressbook: '.$id,OCP\Util::DEBUG);
  169. self::setActive($id, true);
  170. $addressbooks = OC_Contacts_Addressbook::all($uid);
  171. }
  172. $prefbooks[] = $addressbooks[0]['id'];
  173. OCP\Config::setUserValue($uid,'contacts','openaddressbooks',implode(';',$prefbooks));
  174. }
  175. return $prefbooks;
  176. }
  177. /**
  178. * @brief Returns the list of active addressbooks for a specific user.
  179. * @param string $uid
  180. * @return array
  181. */
  182. public static function active($uid){
  183. $active = self::activeIds($uid);
  184. $addressbooks = array();
  185. if(!$active) {
  186. return $addressbooks;
  187. }
  188. $ids_sql = join(',', array_fill(0, count($active), '?'));
  189. $prep = 'SELECT * FROM `*PREFIX*contacts_addressbooks` WHERE `id` IN ('.$ids_sql.') ORDER BY `displayname`';
  190. try {
  191. $stmt = OCP\DB::prepare( $prep );
  192. $result = $stmt->execute($active);
  193. while( $row = $result->fetchRow()){
  194. $addressbooks[] = $row;
  195. }
  196. } catch(Exception $e) {
  197. OCP\Util::writeLog('contacts','OC_Contacts_Addressbook:active:, exception: '.$e->getMessage(),OCP\Util::DEBUG);
  198. OCP\Util::writeLog('contacts','OC_Contacts_Addressbook:active, ids: '.join(',', $active),OCP\Util::DEBUG);
  199. OCP\Util::writeLog('contacts','OC_Contacts_Addressbook::active, SQL:'.$prep,OCP\Util::DEBUG);
  200. }
  201. return $addressbooks;
  202. }
  203. /**
  204. * @brief Activates an addressbook
  205. * @param integer $id
  206. * @param integer $name
  207. * @return boolean
  208. */
  209. public static function setActive($id,$active=true){
  210. // Need these ones for checking uri
  211. //$addressbook = self::find($id);
  212. if(is_null($id)){
  213. $id = 0;
  214. }
  215. $openaddressbooks = self::activeIds();
  216. if($active) {
  217. if(!in_array($id, $openaddressbooks)) {
  218. $openaddressbooks[] = $id;
  219. }
  220. } else {
  221. if(in_array($id, $openaddressbooks)) {
  222. unset($openaddressbooks[array_search($id, $openaddressbooks)]);
  223. }
  224. }
  225. // NOTE: Ugly hack...
  226. $openaddressbooks = self::cleanArray($openaddressbooks, false);
  227. sort($openaddressbooks, SORT_NUMERIC);
  228. // FIXME: I alway end up with a ';' prepending when imploding the array..?
  229. OCP\Config::setUserValue(OCP\USER::getUser(),'contacts','openaddressbooks',implode(';', $openaddressbooks));
  230. return true;
  231. }
  232. /**
  233. * @brief Checks if an addressbook is active.
  234. * @param integer $id ID of the address book.
  235. * @return boolean
  236. */
  237. public static function isActive($id){
  238. //OCP\Util::writeLog('contacts','OC_Contacts_Addressbook::isActive('.$id.'):'.in_array($id, self::activeIds()), OCP\Util::DEBUG);
  239. return in_array($id, self::activeIds());
  240. }
  241. /**
  242. * @brief removes an address book
  243. * @param integer $id
  244. * @return boolean
  245. */
  246. public static function delete($id){
  247. // FIXME: There's no error checking at all.
  248. self::setActive($id, false);
  249. $stmt = OCP\DB::prepare( 'DELETE FROM `*PREFIX*contacts_addressbooks` WHERE `id` = ?' );
  250. $stmt->execute(array($id));
  251. $cards = OC_Contacts_VCard::all($id);
  252. foreach($cards as $card){
  253. OC_Contacts_VCard::delete($card['id']);
  254. }
  255. return true;
  256. }
  257. /**
  258. * @brief Updates ctag for addressbook
  259. * @param integer $id
  260. * @return boolean
  261. */
  262. public static function touch($id){
  263. $stmt = OCP\DB::prepare( 'UPDATE `*PREFIX*contacts_addressbooks` SET `ctag` = `ctag` + 1 WHERE `id` = ?' );
  264. $stmt->execute(array($id));
  265. return true;
  266. }
  267. /**
  268. * @brief Creates a URI for Addressbook
  269. * @param string $name name of the addressbook
  270. * @param array $existing existing addressbook URIs
  271. * @return string new name
  272. */
  273. public static function createURI($name,$existing){
  274. $name = strtolower($name);
  275. $newname = $name;
  276. $i = 1;
  277. while(in_array($newname,$existing)){
  278. $newname = $name.$i;
  279. $i = $i + 1;
  280. }
  281. return $newname;
  282. }
  283. /**
  284. * @brief gets the userid from a principal path
  285. * @return string
  286. */
  287. public static function extractUserID($principaluri){
  288. list($prefix,$userid) = Sabre_DAV_URLUtil::splitPath($principaluri);
  289. return $userid;
  290. }
  291. }