Browse Source

Resync objects (products) after deleted using ref

Mathieu Moulin 11 months ago
parent
commit
a8b30487e4
3 changed files with 181 additions and 14 deletions
  1. 2 0
      src/sync/product/common.inc.php
  2. 6 8
      src/sync/product/pd.inc.php
  3. 173 6
      src/sync/sync.inc.php

+ 2 - 0
src/sync/product/common.inc.php

@@ -24,6 +24,8 @@ const P_SIMPLE_TABLE_MAIN_ID = 'id_product';
 const P_COMBI_TABLE_MAIN = 'product_attribute';
 const P_COMBI_TABLE_MAIN_ID = 'id_product_attribute';
 
+const P_TABLE_MAIN_REF = 'reference';
+
 function d_data($otype, $oid)
 {
 	$data = [];

+ 6 - 8
src/sync/product/pd.inc.php

@@ -2,8 +2,10 @@
 
 class sync_product_pd extends sync_product
 {
-
 	// -- CHECK --
+
+	// No cascade delete
+	const PD_DELETE = false;
 	
 	public static function pd_check_sync(&$o, &$p_data)
 	{
@@ -48,17 +50,13 @@ public function pd_execute_create($otype, $oid)
 	return parent::pd_execute_create($otype, $oid);
 }
 
-public function pd_execute_delete($otype, $oid)
+// -- SUB ACTIONS --
+
+public function pd_delete_more(&$o)
 {
-	if (empty($o = static::p_o_oid('product', $otype, $oid)))
-		return;
-	//ar_dump($o); die();
-	
 	DB::d_update_row('product_extrafields', ['sync'=>0], ['fk_object'=>$o['d_oid']]);
 }
 
-// -- SUB ACTIONS --
-
 public function pd_insert_more(&$o, &$d_data_map, &$p_data)
 {
 	// Un seul cas de $otype/$d_tref dans Doli

+ 173 - 6
src/sync/sync.inc.php

@@ -51,11 +51,14 @@ const D_REF_LENGTH = 5;
 const D_REF_DATE = '';
 
 const P_TABLE_MAIN = '';
+const P_TABLE_MAIN_REF = '';
 const P_TABLE_MAIN_ID = 0;
 
 // Cascade delete
 const DP_DELETE = false;
+const DP_DELETE_LINK = false;
 const PD_DELETE = false;
+const PD_DELETE_LINK = false;
 
 // @todo : déplacer en constante globale !
 
@@ -727,6 +730,32 @@ public static function dp_check_delete(&$o, &$p_data)
 	//return false to block
 }
 
+public static function p_o_byref($type, $otype, $ref)
+{
+	if (empty(static::P_TABLE_MAIN_REF))
+		false;
+
+	$row = DB::p_get_row($otype, [static::P_TABLE_MAIN_REF=>$ref]);
+	if (DEBUG_AFF)
+		var_dump($row);
+
+	if (!empty($row))
+		return static::p_o_oid($type, $otype, $row[static::P_TABLE_ID[$otype]]);
+}
+
+public static function d_o_byref($type, $otype, $ref)
+{
+	if (empty(static::D_TABLE_MAIN_REF))
+		return false;
+
+	$row = DB::d_get_row($otype, [static::D_TABLE_MAIN_REF=>$ref]);
+	if (DEBUG_AFF)
+		var_dump($row);
+
+	if (!empty($row))
+		return static::d_o_oid($type, $otype, $row['rowid']);
+}
+
 // CREATE
 public function pd_create($otype, $oid)
 {
@@ -754,9 +783,65 @@ public function pd_create($otype, $oid)
 		return;
 	}
 	
-	// Construit nouvel objet
 	if (empty($o['d_tref']))
 		$o['d_tref'] = static::D_TABLE_MAIN;
+	if (DEBUG_AFF)
+		var_dump($o);
+
+	// Check Doublon ref unique à resynchroniser
+	if (static::P_TABLE_MAIN_REF && static::D_TABLE_MAIN_REF && !empty($p_data[$otype][static::P_TABLE_MAIN_REF])) {
+		$ref = $p_data[$otype][static::P_TABLE_MAIN_REF];
+		// Object qui a déjà été synchronisé
+		$o2 = static::d_o_byref(static::MODEL_NAME, $otype, $ref);
+		// Données de l'autre côté avec la même ref
+		$d_row = DB::d_get_row($o['d_tref'], [static::D_TABLE_MAIN_REF=>$ref]);
+		if (DEBUG_AFF)
+			var_dump($ref, $o2, $d_row);
+
+		// Trouvé règle de synchro
+		if (!empty($o2)) {
+			// Récupération object p
+			$p_row = DB::p_get_row($o2['p_tref'], ['id_product'=>$o2['p_oid']]);
+			if (DEBUG_AFF)
+				var_dump($p_row);
+			// Si pas d'object on réaffecte
+			if (empty($p_row)) {
+				if (DEBUG_AFF)
+					echo 'REAFFECTER';
+				$sql = 'UPDATE _objects_p op
+					INNER JOIN _p_tables t
+					SET op.oid='.$o['p_oid'].', op.tid=t.id
+					WHERE t.ref="'.$o['p_tref'].'" AND op.id='.$o2['id'];
+				if (DEBUG_AFF)
+					echo $sql;
+				//die();
+				DB::o_update($sql);
+			}
+			// Déjà synchronisé => blocage
+			else {
+				sync_error(__FILE__.':'.__LINE__.' : '.__METHOD__."($otype, $oid)", "Referrence already exists and synced on the other side", $context, NULL, 'ref_exists');
+			}
+			return;
+		}
+		// Réassociation
+		elseif (!empty($d_row)) {
+			// Create Mapping Object
+			$o['d_oid'] = $d_row['rowid'];
+			if (!($this->o_create($o))) {
+				// @todo : delete useless inserted data
+				sync_error(__FILE__.':'.__LINE__.' : '.__METHOD__."($otype, $oid)", "o_create() returns false", $context, NULL, 'object');
+				return;
+			}
+
+			// Sync notif ts
+			static::_notif_ts('p', $otype, $oid);
+			return;
+		}
+	}
+	
+	//die();
+
+	// Construit nouvel objet
 	$d_data_map = $d_data_map_create = $this->pd_map_create($o, $p_data);
 	if (DEBUG_AFF)
 		var_dump($d_data_map);
@@ -847,9 +932,61 @@ public function dp_create($otype, $oid)
 		return;
 	}
 	
-	// Construit données objet & Check
 	if (empty($o['p_tref']))
 		$o['p_tref'] = static::P_TABLE_MAIN;
+
+	// Check Doublon ref à resynchroniser
+	if (static::D_TABLE_MAIN_REF && static::P_TABLE_MAIN_REF && !empty($d_data[$otype][static::D_TABLE_MAIN_REF])) {
+		$ref = $d_data[$otype][static::D_TABLE_MAIN_REF];
+		// Object qui a déjà été synchronisé
+		$o2 = static::p_o_byref(static::MODEL_NAME, $otype, $ref);
+		// Données de l'autre côté avec la même ref
+		$p_row = DB::p_get_row($o['p_tref'], [static::P_TABLE_MAIN_REF=>$ref]);
+		if (DEBUG_AFF)
+			var_dump($o2, $p_row);
+
+		// Trouvé règle de synchro
+		if (!empty($o2)) {
+			// Récupération object p
+			$p_row = DB::p_get_row($o2['p_tref'], ['id_product'=>$o2['p_oid']]);
+			if (DEBUG_AFF)
+				var_dump($p_row);
+			// Si pas d'object on réaffecte
+			if (empty($p_row)) {
+				if (DEBUG_AFF)
+					echo 'REAFFECTER';
+				$sql = 'UPDATE _objects_p op
+					INNER JOIN _p_tables t
+					SET op.oid='.$o['p_oid'].', op.tid=t.id
+					WHERE t.ref="'.$o['p_tref'].'" op.id='.$o2['id'];
+				if (DEBUG_AFF)
+					echo $sql;
+				//die();
+				DB::o_update($sql);
+			}
+			// Déjà synchronisé => blocage
+			else {
+				sync_error(__FILE__.':'.__LINE__.' : '.__METHOD__."($otype, $oid)", "Referrence already exists and synced on the other side", $context, NULL, 'ref_exists');
+			}
+			return;
+		}
+		// Réassociation (fonctionne si une seule table... sinon il faut boucler/chercher dans product et product_attribute par ex.)
+		elseif (!empty($p_row)) {
+			// Create Mapping Object
+			$o['p_oid'] = $p_row[static::P_TABLE_ID[$o['p_tref']]];
+			if (!($this->o_create($o))) {
+				// @todo : delete useless inserted data
+				sync_error(__FILE__.':'.__LINE__.' : '.__METHOD__."($otype, $oid)", "o_create() returns false", $context, NULL, 'object');
+				return;
+			}
+
+			// Sync notif ts
+			static::_notif_ts('d', $otype, $oid);
+			return;
+		}
+	}
+
+	// Construit données objet & Check
 	$p_data_map = $p_data_map_create = $this->dp_map_create($o, $d_data);
 	if (is_null($p_data_map)) {
 		sync_error(__FILE__.':'.__LINE__.' : '.__METHOD__."($otype, $oid)", "map_create() : NULL", $context, NULL, 'nodatamap');
@@ -1067,21 +1204,36 @@ public function pd_delete(&$o)
 	//var_dump($context); die();
 
 	$d_data = $this->d_data($o['d_tref'], $o['d_oid']);
+	// Check cascade delete
 	if (!($check_sync=$this->pd_check_delete($o, $d_data))) {
 		if (DEBUG_AFF)
 			var_dump($check_sync);
+
+		// Delete more
+		// In that case this is more a delete substitute
+		$this->pd_delete_more($o);
+
+		if (static::PD_DELETE_LINK) {
+			$sql = 'DELETE FROM _objects WHERE id='.$o['id'];
+			DB::o_delete($sql);
+		}
+		
 		if ($check_sync!==false)
 			sync_error(__FILE__.':'.__LINE__.' : '.__METHOD__."($o[d_tref], $o[d_oid])", "Object marked not to delete", $context, NULL, 'nosync');
+		else
+			static::_notif_ts('p', $o['p_tref'], $o['p_oid']);
+
 		return false;
 	}
+
 	if (! ($r=DB::d_delete_row($o['d_tref'], ['rowid'=>$o['d_oid']]))) {
 		sync_error(__FILE__.':'.__LINE__.' : '.__METHOD__."($o[d_tref], $o[d_oid])", "Source data does not exists", $context, NULL, 'nodata');
 		return false;
 	}
 	//$r=DB::p_delete_row($o['p_tref']], [static::P_TABLE_ID[$o['p_tref']]]=>$o['p_oid']]);
 	
-	// Update more
-	$this->dp_delete_more($o);
+	// Delete more
+	$this->pd_delete_more($o);
 
 	// Delete link object (@todo check if this is a good idea... maybe it would be better to keep the link..?)
 	$sql = 'DELETE FROM _objects WHERE id='.$o['id'];
@@ -1092,7 +1244,7 @@ public function pd_delete(&$o)
 	
 	return true;
 }
-public function dp_delete_more(&$o)
+public function pd_delete_more(&$o)
 {
 	// Overload
 }
@@ -1104,13 +1256,28 @@ public function dp_delete(&$o)
 	$context = ['type'=>static::MODEL_NAME, 'sens'=>'dp', 'action'=>'delete', 'otype'=>$o['p_tref'], 'oid'=>$o['p_oid']];
 
 	$p_data = $this->p_data($o['p_tref'], $o['p_oid']);
+	// Check cascade delete
 	if (!($check_sync=$this->dp_check_delete($o, $p_data))) {
 		if (DEBUG_AFF)
 			var_dump($check_sync);
+
+		// Delete more
+		// In that case this is more a delete substitute
+		$this->dp_delete_more($o);
+
+		if (static::DP_DELETE_LINK) {
+			$sql = 'DELETE FROM _objects WHERE id='.$o['id'];
+			DB::o_delete($sql);
+		}
+
 		if ($check_sync!==false)
 			sync_error(__FILE__.':'.__LINE__.' : '.__METHOD__."($o[p_tref], $o[p_oid])", "Object marked not to delete", $context, NULL, 'nosync');
+		else
+			static::_notif_ts('d', $o['d_tref'], $o['d_oid']);
+
 		return false;
 	}
+
 	if (! ($r=DB::p_delete_row($o['p_tref'], [static::P_TABLE_ID[$o['p_tref']]=>$o['p_oid']]))) {
 		sync_error(__FILE__.':'.__LINE__.' : '.__METHOD__."($o[p_tref], $o[p_oid])", "Source data does not exists", $context, NULL, 'nodata');
 		return false;
@@ -1128,7 +1295,7 @@ public function dp_delete(&$o)
 
 	return true;
 }
-public function pd_delete_more(&$o)
+public function dp_delete_more(&$o)
 {
 	// Overload
 }