FieldsController.php 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. <?php
  2. final class NF_Database_FieldsController
  3. {
  4. private $db;
  5. private $factory;
  6. private $fields_data;
  7. private $new_field_ids;
  8. private $insert_fields;
  9. private $insert_field_meta = array();
  10. private $insert_field_meta_chunk = 0;
  11. private $update_fields = array( 'key' => '', 'label' => '', 'type' => '' );
  12. private $update_field_meta = array();
  13. private $update_field_meta_chunk = 0;
  14. public function __construct( $form_id, $fields_data )
  15. {
  16. global $wpdb;
  17. $this->db = $wpdb;
  18. $this->form_id = $form_id;
  19. $this->fields_data = $fields_data;
  20. }
  21. public function run()
  22. {
  23. $this->db->hide_errors();
  24. /* FIELDS */
  25. $this->parse_fields();
  26. $insert_fields_query = $this->get_insert_fields_query();
  27. if( ! empty( $insert_fields_query ) ){
  28. $this->db->query( $insert_fields_query );
  29. $this->update_new_field_ids();
  30. }
  31. $update_fields_query = $this->get_update_fields_query();
  32. if( ! empty( $update_fields_query ) ){
  33. $this->db->query( $update_fields_query );
  34. }
  35. /* FIELD META */
  36. $this->parse_field_meta();
  37. $this->run_insert_field_meta_query();
  38. $this->run_update_field_meta_query();
  39. }
  40. public function get_updated_fields_data()
  41. {
  42. return $this->fields_data;
  43. }
  44. private function parse_fields()
  45. {
  46. foreach( $this->fields_data as $field_data ){
  47. $field_id = $field_data[ 'id' ];
  48. $settings = array(
  49. 'key' => $field_data[ 'settings' ][ 'key' ],
  50. 'label' => $field_data[ 'settings' ][ 'label' ],
  51. 'type' => $field_data[ 'settings' ][ 'type' ]
  52. );
  53. if( ! is_numeric( $field_id ) ) {
  54. $this->insert_field( $settings ); // New Field.
  55. } else {
  56. $this->update_field( $field_id, $settings );
  57. }
  58. }
  59. }
  60. private function parse_field_meta()
  61. {
  62. $existing_meta = $this->get_existing_meta();
  63. foreach( $this->fields_data as $field_data ){
  64. $field_id = $field_data[ 'id' ];
  65. foreach( $field_data[ 'settings' ] as $key => $value ){
  66. // we don't need object type or domain stored in the db
  67. if( ! in_array( $key, array( 'objectType', 'objectDomain' ) ) ) {
  68. if( isset( $existing_meta[ $field_id ][ $key ] ) ){
  69. if( $value == $existing_meta[ $field_id ][ $key ] ) continue;
  70. $this->update_field_meta( $field_id, $key, $value );
  71. } else {
  72. $this->insert_field_meta( $field_id, $key, $value );
  73. }
  74. }
  75. }
  76. }
  77. }
  78. private function get_existing_meta()
  79. {
  80. $results = $this->db->get_results("
  81. SELECT m.parent_id, m.key, m.value
  82. FROM `{$this->db->prefix}nf3_field_meta` AS m
  83. LEFT JOIN `{$this->db->prefix}nf3_fields` AS f
  84. ON m.parent_id = f.id
  85. WHERE f.parent_id = {$this->form_id}
  86. ");
  87. $field_meta = array();
  88. foreach( $results as $meta ){
  89. if( ! isset( $field_meta[ $meta->parent_id ] ) ) $field_meta[ $meta->parent_id ] = array();
  90. $field_meta[ $meta->parent_id ][ $meta->key ] = $meta->value;
  91. }
  92. return $field_meta;
  93. }
  94. private function update_new_field_ids()
  95. {
  96. $field_id_lookup = $this->db->get_results("
  97. SELECT `key`, `id`
  98. FROM {$this->db->prefix}nf3_fields
  99. WHERE `parent_id` = {$this->form_id}
  100. ", OBJECT_K);
  101. foreach( $this->fields_data as $i => $field_data ){
  102. $field_key = $field_data[ 'settings' ][ 'key' ];
  103. if( ! is_numeric( $field_data[ 'id' ] ) && isset( $field_id_lookup[ $field_key ] ) ){
  104. $tmp_id = $field_data[ 'id' ];
  105. $this->fields_data[ $i ][ 'id' ] = $this->new_field_ids[ $tmp_id ] = $field_id_lookup[ $field_key ]->id;
  106. }
  107. }
  108. }
  109. public function get_new_field_ids()
  110. {
  111. return $this->new_field_ids;
  112. }
  113. /*
  114. |--------------------------------------------------------------------------
  115. | INSERT (NEW) FIELDS
  116. |--------------------------------------------------------------------------
  117. */
  118. private function insert_field( $settings )
  119. {
  120. $this->insert_fields .= "(";
  121. foreach ( $settings as $setting => $value ) {
  122. $this->db->escape_by_ref( $value );
  123. $this->insert_fields .= "'{$value}',";
  124. }
  125. $this->insert_fields .= "'{$this->form_id}'";
  126. $this->insert_fields .= '),';
  127. }
  128. public function get_insert_fields_query()
  129. {
  130. if( ! $this->insert_fields ) return "";
  131. $insert_fields = rtrim( $this->insert_fields, ',' ); // Strip trailing comma from SQl.
  132. return "
  133. INSERT INTO {$this->db->prefix}nf3_fields ( `key`, `label`, `type`, `parent_id` )
  134. VALUES {$insert_fields}
  135. ";
  136. }
  137. /*
  138. |--------------------------------------------------------------------------
  139. | UPDATE (EXISTING) FIELDS
  140. |--------------------------------------------------------------------------
  141. */
  142. private function update_field( $field_id, $settings )
  143. {
  144. foreach ( $settings as $setting => $value ) {
  145. $line = "WHEN `id` = '{$field_id}' ";
  146. $this->db->escape_by_ref( $value );
  147. $line .= "THEN '{$value}'";
  148. $this->update_fields[ $setting ] .= $line;
  149. }
  150. }
  151. public function get_update_fields_query()
  152. {
  153. if(
  154. empty( $this->update_fields[ 'key' ] ) ||
  155. empty( $this->update_fields[ 'label' ] ) ||
  156. empty( $this->update_fields[ 'type' ] )
  157. ) return "";
  158. return "
  159. UPDATE {$this->db->prefix}nf3_fields
  160. SET `key` = CASE {$this->update_fields[ 'key' ]}
  161. ELSE `key`
  162. END
  163. , `label` = CASE {$this->update_fields[ 'label' ]}
  164. ELSE `label`
  165. END
  166. , `type` = CASE {$this->update_fields[ 'type' ]}
  167. ELSE `type`
  168. END
  169. ";
  170. }
  171. /*
  172. |--------------------------------------------------------------------------
  173. | INSERT (NEW) META
  174. |--------------------------------------------------------------------------
  175. */
  176. private function insert_field_meta( $field_id, $key, $value )
  177. {
  178. static $counter;
  179. $value = maybe_serialize( $value );
  180. $this->db->escape_by_ref( $field_id );
  181. $this->db->escape_by_ref( $key );
  182. $this->db->escape_by_ref( $value );
  183. if( ! isset( $this->insert_field_meta[ $this->insert_field_meta_chunk ] ) || ! $this->insert_field_meta[ $this->insert_field_meta_chunk ] ) {
  184. $this->insert_field_meta[ $this->insert_field_meta_chunk ] = '';
  185. }
  186. $this->insert_field_meta[ $this->insert_field_meta_chunk ] .= "('{$field_id}','{$key}','{$value}' ),";
  187. $counter++;
  188. if( 0 == $counter % 5000 ) $this->insert_field_meta_chunk++;
  189. }
  190. public function run_insert_field_meta_query()
  191. {
  192. if( ! $this->insert_field_meta ) return "";
  193. foreach( $this->insert_field_meta as $insert_field_meta ){
  194. $insert_field_meta = rtrim( $insert_field_meta, ',' ); // Strip trailing comma from SQl.
  195. $this->db->query( "
  196. INSERT INTO {$this->db->prefix}nf3_field_meta ( `parent_id`, `key`, `value` )
  197. VALUES {$insert_field_meta}
  198. ");
  199. }
  200. }
  201. /*
  202. |--------------------------------------------------------------------------
  203. | UPDATE (EXISTING) META
  204. |--------------------------------------------------------------------------
  205. */
  206. private function update_field_meta( $field_id, $key, $value )
  207. {
  208. static $counter;
  209. $value = maybe_serialize( $value );
  210. $this->db->escape_by_ref( $key );
  211. $this->db->escape_by_ref( $value );
  212. if( ! isset( $this->update_field_meta[ $this->update_field_meta_chunk ] ) || ! $this->update_field_meta[ $this->update_field_meta_chunk ] ) {
  213. $this->update_field_meta[ $this->update_field_meta_chunk ] = '';
  214. }
  215. $this->update_field_meta[ $this->update_field_meta_chunk ] .= " WHEN `parent_id` = '{$field_id}' AND `key` = '{$key}' THEN '{$value}'";
  216. $counter++;
  217. if( 0 == $counter % 5000 ) $this->update_field_meta_chunk++;
  218. }
  219. public function run_update_field_meta_query()
  220. {
  221. if( empty( $this->update_field_meta ) ) return '';
  222. foreach( $this->update_field_meta as $update_field_meta ){
  223. $this->db->query("
  224. UPDATE {$this->db->prefix}nf3_field_meta as field_meta
  225. SET `value` = CASE {$update_field_meta} ELSE `value` END
  226. ");
  227. return;
  228. }
  229. }
  230. }