| 
									
										
										
										
											2013-07-19 18:52:52 +03:00
										 |  |  | <?php | 
					
						
							| 
									
										
										
										
											2013-08-08 00:22:21 +03:00
										 |  |  | /** | 
					
						
							| 
									
										
										
										
											2015-12-16 17:57:44 +03:00
										 |  |  |  * ownCloud - Richdocuments App | 
					
						
							| 
									
										
										
										
											2013-08-08 00:22:21 +03:00
										 |  |  |  * | 
					
						
							|  |  |  |  * @author Victor Dubiniuk | 
					
						
							|  |  |  |  * @copyright 2013 Victor Dubiniuk victor.dubiniuk@gmail.com | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This file is licensed under the Affero General Public License version 3 or | 
					
						
							|  |  |  |  * later. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2013-07-19 18:52:52 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-16 17:57:44 +03:00
										 |  |  | namespace OCA\Richdocuments\Db; | 
					
						
							| 
									
										
										
										
											2013-07-19 18:52:52 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-16 17:57:44 +03:00
										 |  |  | class Op extends \OCA\Richdocuments\Db { | 
					
						
							| 
									
										
										
										
											2013-07-20 18:56:09 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-16 17:57:44 +03:00
										 |  |  | 	const DB_TABLE = '`*PREFIX*richdocuments_op`'; | 
					
						
							| 
									
										
										
										
											2013-09-07 21:26:22 +03:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2015-12-16 17:57:44 +03:00
										 |  |  | 	protected $tableName = '`*PREFIX*richdocuments_op`'; | 
					
						
							| 
									
										
										
										
											2013-08-06 18:07:05 +03:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2015-12-16 17:57:44 +03:00
										 |  |  | 	protected $insertStatement = 'INSERT INTO `*PREFIX*richdocuments_op` (`es_id`, `optype`, `member`, `opspec`) VALUES (?, ?, ?, ?)'; | 
					
						
							| 
									
										
										
										
											2013-09-27 18:43:10 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-07 16:49:52 +03:00
										 |  |  | 	public static function addOpsArray($esId, $memberId, $ops){ | 
					
						
							| 
									
										
										
										
											2014-08-04 20:56:24 +03:00
										 |  |  | 		$opObj = new Op(); | 
					
						
							| 
									
										
										
										
											2013-08-07 16:49:52 +03:00
										 |  |  | 		foreach ($ops as $op) { | 
					
						
							| 
									
										
										
										
											2014-11-13 20:05:58 +03:00
										 |  |  | 			if (!$opObj->canInsertOp($esId, $memberId, $op)){ | 
					
						
							|  |  |  | 				continue; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2013-09-27 18:43:10 +03:00
										 |  |  | 			$opObj->setData(array( | 
					
						
							| 
									
										
										
										
											2014-11-13 01:20:54 +03:00
										 |  |  | 				$esId, | 
					
						
							|  |  |  | 				$op['optype'], | 
					
						
							|  |  |  | 				$memberId, | 
					
						
							| 
									
										
										
										
											2013-09-27 18:43:10 +03:00
										 |  |  | 				json_encode($op) | 
					
						
							|  |  |  | 			)); | 
					
						
							|  |  |  | 			$opObj->insert(); | 
					
						
							| 
									
										
										
										
											2013-08-07 16:49:52 +03:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-11-13 20:05:58 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		return $opObj->getHeadSeq($esId); | 
					
						
							| 
									
										
										
										
											2013-08-07 16:49:52 +03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-09-27 18:43:10 +03:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2013-08-07 13:04:32 +02:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @returns "" when there are no Ops, or the seq of the last Op | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2013-09-27 18:43:10 +03:00
										 |  |  | 	public function getHeadSeq($esId){ | 
					
						
							| 
									
										
										
										
											2015-08-28 19:32:54 +03:00
										 |  |  | 		$query = \OC::$server->getDatabaseConnection()->prepare(' | 
					
						
							| 
									
										
										
										
											2013-08-28 15:24:41 +02:00
										 |  |  | 			SELECT `seq` | 
					
						
							| 
									
										
										
										
											2013-09-27 18:43:10 +03:00
										 |  |  | 			FROM ' . $this->tableName . ' | 
					
						
							| 
									
										
										
										
											2013-08-28 15:24:41 +02:00
										 |  |  | 			WHERE `es_id`=? | 
					
						
							| 
									
										
										
										
											2013-09-02 17:15:29 +02:00
										 |  |  | 			ORDER BY `seq` DESC | 
					
						
							| 
									
										
										
										
											2013-08-28 15:24:41 +02:00
										 |  |  | 			', 1); | 
					
						
							| 
									
										
										
										
											2015-08-28 19:32:54 +03:00
										 |  |  | 		$result = $query->execute([$esId]); | 
					
						
							|  |  |  | 		return !$result ? "" : $query->fetchColumn(); | 
					
						
							| 
									
										
										
										
											2013-08-07 16:49:52 +03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2013-09-27 18:43:10 +03:00
										 |  |  | 	public function getOpsAfterJson($esId, $seq){ | 
					
						
							|  |  |  | 		$ops = $this->getOpsAfter($esId, $seq); | 
					
						
							| 
									
										
										
										
											2013-08-12 19:07:44 +03:00
										 |  |  | 		if (!is_array($ops)){ | 
					
						
							|  |  |  | 			$ops = array(); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-08-07 19:01:50 +03:00
										 |  |  | 		$ops =  array_map( | 
					
						
							| 
									
										
										
										
											2013-08-12 15:53:27 +03:00
										 |  |  | 				function($x){ | 
					
						
							| 
									
										
										
										
											2013-08-12 19:07:44 +03:00
										 |  |  | 					$decoded = json_decode($x['opspec'], true); | 
					
						
							|  |  |  | 					$decoded['memberid'] = strval($decoded['memberid']); | 
					
						
							| 
									
										
										
										
											2013-08-12 15:53:27 +03:00
										 |  |  | 					return $decoded; | 
					
						
							|  |  |  | 				},  | 
					
						
							| 
									
										
										
										
											2013-08-07 19:01:50 +03:00
										 |  |  | 				$ops | 
					
						
							| 
									
										
										
										
											2013-08-07 16:49:52 +03:00
										 |  |  | 		); | 
					
						
							| 
									
										
										
										
											2013-08-07 19:01:50 +03:00
										 |  |  | 		return $ops; | 
					
						
							| 
									
										
										
										
											2013-08-06 18:07:05 +03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2013-09-27 18:43:10 +03:00
										 |  |  | 	public function getOpsAfter($esId, $seq){ | 
					
						
							| 
									
										
										
										
											2013-08-07 16:49:52 +03:00
										 |  |  | 		if ($seq == ""){ | 
					
						
							|  |  |  | 			$seq = -1; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-08-28 19:32:54 +03:00
										 |  |  | 		$query = \OC::$server->getDatabaseConnection()->prepare(' | 
					
						
							| 
									
										
										
										
											2013-08-28 15:24:41 +02:00
										 |  |  | 			SELECT `opspec` | 
					
						
							| 
									
										
										
										
											2013-09-07 21:26:22 +03:00
										 |  |  | 			FROM ' . self::DB_TABLE . ' | 
					
						
							| 
									
										
										
										
											2013-08-28 15:24:41 +02:00
										 |  |  | 			WHERE `es_id`=? | 
					
						
							|  |  |  | 				AND `seq`>? | 
					
						
							|  |  |  | 			ORDER BY `seq` ASC | 
					
						
							|  |  |  | 			'); | 
					
						
							| 
									
										
										
										
											2015-09-19 00:37:16 +03:00
										 |  |  | 		$query->execute(array($esId, $seq)); | 
					
						
							| 
									
										
										
										
											2015-08-28 19:32:54 +03:00
										 |  |  | 		return $query->fetchAll(); | 
					
						
							| 
									
										
										
										
											2013-07-20 18:56:09 +03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-11-25 21:26:40 +03:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2014-11-19 03:37:09 +03:00
										 |  |  | 	public function addMember($esId, $memberId, $fullName, $userId, $color, $imageUrl){ | 
					
						
							| 
									
										
										
										
											2014-11-13 01:20:54 +03:00
										 |  |  | 		$op = array( | 
					
						
							|  |  |  | 			'optype' => 'AddMember', | 
					
						
							|  |  |  | 			'memberid' => (string) $memberId, | 
					
						
							| 
									
										
										
										
											2015-08-25 21:18:48 +03:00
										 |  |  | 			'timestamp' => $this->getMillisecondsAsString(), | 
					
						
							| 
									
										
										
										
											2014-11-13 01:20:54 +03:00
										 |  |  | 			'setProperties' => array( | 
					
						
							|  |  |  | 				'fullName' => $fullName, | 
					
						
							|  |  |  | 				'color' => $color, | 
					
						
							| 
									
										
										
										
											2014-11-19 03:37:09 +03:00
										 |  |  | 				'imageUrl' => $imageUrl, | 
					
						
							|  |  |  | 				'uid' => $userId, | 
					
						
							| 
									
										
										
										
											2014-11-13 01:20:54 +03:00
										 |  |  | 			) | 
					
						
							|  |  |  | 		); | 
					
						
							| 
									
										
										
										
											2014-03-05 18:47:06 +03:00
										 |  |  | 		$this->insertOp($esId, $memberId, $op); | 
					
						
							| 
									
										
										
										
											2013-11-25 21:26:40 +03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2014-02-12 17:28:26 +03:00
										 |  |  | 	public function removeCursor($esId, $memberId){ | 
					
						
							| 
									
										
										
										
											2014-11-13 01:20:54 +03:00
										 |  |  | 		$op = array( | 
					
						
							|  |  |  | 			'optype' => 'RemoveCursor', | 
					
						
							|  |  |  | 			'memberid' => (string) $memberId, | 
					
						
							|  |  |  | 			'reason' => 'server-idle', | 
					
						
							| 
									
										
										
										
											2015-08-25 21:18:48 +03:00
										 |  |  | 			'timestamp' => $this->getMillisecondsAsString() | 
					
						
							| 
									
										
										
										
											2014-11-13 01:20:54 +03:00
										 |  |  | 		); | 
					
						
							| 
									
										
										
										
											2014-11-13 20:05:58 +03:00
										 |  |  | 		$this->insertOp($esId, $memberId, $op); | 
					
						
							| 
									
										
										
										
											2014-02-12 17:28:26 +03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2013-11-25 21:26:40 +03:00
										 |  |  | 	public function removeMember($esId, $memberId){ | 
					
						
							| 
									
										
										
										
											2014-11-13 01:20:54 +03:00
										 |  |  | 		$op = array( | 
					
						
							|  |  |  | 			'optype' => 'RemoveMember', | 
					
						
							|  |  |  | 			'memberid' => (string) $memberId, | 
					
						
							| 
									
										
										
										
											2015-08-25 21:18:48 +03:00
										 |  |  | 			'timestamp' => $this->getMillisecondsAsString() | 
					
						
							| 
									
										
										
										
											2014-11-13 01:20:54 +03:00
										 |  |  | 		); | 
					
						
							| 
									
										
										
										
											2014-11-13 20:05:58 +03:00
										 |  |  | 		$this->insertOp($esId, $memberId, $op); | 
					
						
							| 
									
										
										
										
											2013-11-25 21:26:40 +03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2014-11-13 01:34:44 +03:00
										 |  |  | 	//TODO: Implement https://github.com/kogmbh/WebODF/blob/master/webodf/lib/ops/OpUpdateMember.js#L95
 | 
					
						
							| 
									
										
										
										
											2014-03-14 20:49:17 +03:00
										 |  |  | 	public function changeNick($esId, $memberId, $fullName){ | 
					
						
							| 
									
										
										
										
											2014-11-13 01:20:54 +03:00
										 |  |  | 		$op = array( | 
					
						
							|  |  |  | 			'optype' => 'UpdateMember', | 
					
						
							|  |  |  | 			'memberid' => (string) $memberId, | 
					
						
							| 
									
										
										
										
											2015-08-25 21:18:48 +03:00
										 |  |  | 			'timestamp' => $this->getMillisecondsAsString(), | 
					
						
							| 
									
										
										
										
											2014-11-13 01:20:54 +03:00
										 |  |  | 			'setProperties' => array( | 
					
						
							|  |  |  | 				'fullName' => $fullName, | 
					
						
							|  |  |  | 			) | 
					
						
							|  |  |  | 		); | 
					
						
							| 
									
										
										
										
											2014-03-14 20:49:17 +03:00
										 |  |  | 		$this->insertOp($esId, $memberId, $op); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2014-03-05 18:47:06 +03:00
										 |  |  | 	protected function insertOp($esId, $memberId, $op){ | 
					
						
							| 
									
										
										
										
											2014-11-13 20:05:58 +03:00
										 |  |  | 		if ($this->canInsertOp($esId, $memberId, $op)){ | 
					
						
							|  |  |  | 			$op = new Op(array( | 
					
						
							|  |  |  | 				$esId, | 
					
						
							|  |  |  | 				$op['optype'], | 
					
						
							|  |  |  | 				$memberId, | 
					
						
							|  |  |  | 				json_encode($op) | 
					
						
							|  |  |  | 			)); | 
					
						
							|  |  |  | 			$op->insert(); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-08-17 18:32:24 +03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-11-25 21:26:40 +03:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2014-11-13 20:05:58 +03:00
										 |  |  | 	protected function canInsertOp($esId, $memberId, $op){ | 
					
						
							|  |  |  | 		$cursorOps = array('AddCursor', 'RemoveCursor'); | 
					
						
							|  |  |  | 		$memberOps = array('AddMember', 'RemoveMember'); | 
					
						
							|  |  |  | 		$result = true; | 
					
						
							| 
									
										
										
										
											2014-03-05 18:47:06 +03:00
										 |  |  | 		 | 
					
						
							| 
									
										
										
										
											2014-11-13 20:05:58 +03:00
										 |  |  | 		switch ($op['optype']){ | 
					
						
							|  |  |  | 			case 'AddCursor': | 
					
						
							|  |  |  | 				$ops = $this->getFilteredMemberOps($esId, $memberId, $cursorOps); | 
					
						
							|  |  |  | 				$result = !count($ops) || $ops[0]['optype'] === 'RemoveCursor'; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			case 'RemoveCursor': | 
					
						
							|  |  |  | 				$ops = $this->getFilteredMemberOps($esId, $memberId, $cursorOps); | 
					
						
							|  |  |  | 				$result = count($ops) && $ops[0]['optype'] === 'AddCursor'; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			case 'AddMember': | 
					
						
							|  |  |  | 				$ops = $this->getFilteredMemberOps($esId, $memberId, $memberOps); | 
					
						
							|  |  |  | 				$result = !count($ops) || $ops[0]['optype'] === 'RemoveMember'; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			case 'RemoveMember': | 
					
						
							|  |  |  | 				$ops = $this->getFilteredMemberOps($esId, $memberId, $memberOps); | 
					
						
							|  |  |  | 				$result = count($ops) && $ops[0]['optype'] === 'AddMember'; | 
					
						
							|  |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2014-03-05 18:47:06 +03:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-11-13 20:05:58 +03:00
										 |  |  | 		return $result; | 
					
						
							| 
									
										
										
										
											2014-03-05 18:47:06 +03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-11-13 20:05:58 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	protected function getFilteredMemberOps($esId, $memberId, $targetOps){ | 
					
						
							|  |  |  | 		$stmt = $this->buildInQuery('optype', $targetOps); | 
					
						
							|  |  |  | 		$result = $this->execute(' | 
					
						
							|  |  |  | 			SELECT `optype` FROM ' . $this->tableName . ' | 
					
						
							|  |  |  | 			WHERE es_id=? AND member=? AND ' . $stmt . 'ORDER BY `seq` DESC', | 
					
						
							|  |  |  | 			array_merge(array($esId, $memberId), $targetOps) | 
					
						
							| 
									
										
										
										
											2013-12-06 19:54:30 +03:00
										 |  |  | 		); | 
					
						
							| 
									
										
										
										
											2014-11-13 20:05:58 +03:00
										 |  |  | 		$ops = $result->fetchAll(); | 
					
						
							|  |  |  | 		if (!is_array($ops)){ | 
					
						
							|  |  |  | 			$ops = array(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return $ops; | 
					
						
							| 
									
										
										
										
											2013-12-06 19:54:30 +03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-08-25 21:18:48 +03:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	protected function getMillisecondsAsString(){ | 
					
						
							|  |  |  | 		$microtime = microtime(); | 
					
						
							|  |  |  | 		list($usec, $sec) = explode(" ", $microtime); | 
					
						
							|  |  |  | 		$milliseconds = $sec.substr($usec, 2, 3); | 
					
						
							|  |  |  | 		return $milliseconds; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-07-19 18:52:52 +03:00
										 |  |  | } |