AnonSec Shell
Server IP : 54.36.91.62  /  Your IP : 216.73.217.117
Web Server : Apache
System : Linux webm013.cluster127.gra.hosting.ovh.net 5.15.206-ovh-vps-grsec-zfs-classid #1 SMP Fri May 15 02:41:25 UTC 2026 x86_64
User : coopiak ( 151928)
PHP Version : 8.3.23
Disable Function : _dyuweyrj4,_dyuweyrj4r,dl
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /home/coopiak/departement-amisdessenior-.fr/libraries/CBLib/CB/Legacy/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ HOME ]     

Current File : /home/coopiak/departement-amisdessenior-.fr/libraries/CBLib/CB/Legacy/cbSqlQueryPart.php
<?php
/**
* CBLib, Community Builder Library(TM)
* @version $Id: 6/18/14 2:31 PM $
* @copyright (C) 2004-2023 www.joomlapolis.com / Lightning MultiCom SA - and its licensors, all rights reserved
* @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU/GPL version 2
*/

use CBLib\Application\Application;

defined('CBLIB') or die();

/**
 * cbSqlQueryPart Class implementation
 * SQL query-compiler for lists searches (in PHP)
 * (Could have extended SimpleXMLElement, but not needed here)
 */
#[\AllowDynamicProperties]
class cbSqlQueryPart
{
	/**
	 * Node tag name ('column', 'where', 'joinkeys', 'data')
	 * @var string
	 */
	public $tag;
	/**
	 * Node name (column name)
	 * @var string
	 */
	public $name;
	/**
	 * Node table name (name of table)
	 * @var string
	 */
	public $table;
	/**
	 * Node type
	 * @var string
	 */
	public $type;
	/**
	 * Operator of the node
	 * @var string
	 */
	public $operator;
	/**
	 * Value of the node
	 * @var string
	 */
	public $value;
	/**
	 * Value type of the node
	 * @var string
	 */
	public $valuetype;
	/**
	 * Search mode for the node
	 * @var string
	 */
	public $searchmode;
	/**
	 * Search-mode: @see cbFieldHandler::_fieldSearchModeHtml()
	 * @var string
	 */
	public $valuetable;
	/**
	 * Key for joins
	 * @var string
	 */
	public $key;
	/**
	 * JSON key paths
	 * @var array
	 */
	public $paths;

	/**
	 * @var cbSqlQueryPart
	 */
	protected $_json		=	null;
	/**
	 * @var cbSqlQueryPart[]
	 */
	protected $_children	=	array();

	/**
	 * Adds children to $this
	 *
	 * @param  cbSqlQueryPart[]  $children
	 */
	public function addChildren( $children )
	{
		$this->_children	=	array_merge( $this->_children, $children );
	}

	/**
	 * Compiles $this SQL query into a real SQL query
	 *
	 * @param  array    $tableReferences
	 * @param  array    $joinsSQL
	 * @param  boolean  $wildcards        TRUE only at top recursion
	 * @return null|string
	 */
	public function reduceSqlFormula( &$tableReferences, &$joinsSQL, $wildcards = null )
	{
		static $replaceWildcards			=	false;
		static $joinedTableKey				=	'a';

		if ( $wildcards !== null ) {
			// Top call of recursion:
			$replaceWildcards				=	$wildcards;
			$joinedTableKey					=	'a';
		}
		$condition							=	null;

		$subFormulas						=	array();

		switch ( $this->getName() ) {
			case 'data':
				$table						=	$this->attributes( 'table' );
				if ( $table ) {
					if ( isset( $tableReferences[$table] ) ) {
						$prevJoinKey			=	$tableReferences[$table];
					} else {
						$prevJoinKey			=	null;
					}
					$joinKey					=	'j' . $joinedTableKey;
					$tableReferences[$table]	=	$joinKey;
					$joinedTableKey				=	chr( ord( $joinedTableKey ) + 1 );
				} else {
					$joinKey				=	null;
					$prevJoinKey			=	null;
				}
				break;

			default:
				$table						=	null;
				$joinKey					=	null;
				$prevJoinKey				=	null;
				break;
		}

		// Recurse:
		foreach ( $this->children() as $child ) {
			if ( $this->_json || ( $this->tag == 'json' ) ) {
				// If the parent is a root JSON node or its a child of a root JSON node then pass this to the child:
				$child->_json				=	( $this->_json ? $this->_json : ( $this->tag == 'json' ? $this : null ) );
			}

			$subForm						=	$child->reduceSqlFormula( $tableReferences, $joinsSQL, null );
			if ( $subForm != '' ) {
				$subFormulas[]				=	$subForm;
			}
		}

		switch ( $this->getName() ) {
			case 'data':
				if ( substr( $this->attributes( 'type' ), 0, 6 ) == 'const:' ) {
					$condition					=	$this->_sqlCleanQuote( $this->attributes( 'value' ), $this->attributes( 'type' ) );
				} else {
					global $_CB_database;

					$joinType					=	'LEFT';
					if ( count( $subFormulas ) > 0 ) {
						$condition				=	'(' . implode( ') ' . $this->attributes( 'operator' ) . ' (', $subFormulas ) . ')';
						foreach ( $this->children() as $child ) {
							if ( $child->getName() == 'joinkeys' ) {
								if ( $child->attributes( 'type' ) === 'inner' ) {
									$joinType	=	'INNER';
								}
								break;
							}
						}
					} else {
						$condition				=	( $joinKey ? $joinKey . '.' : '' ) . $_CB_database->NameQuote( $this->attributes( 'key' ) ) . ' = ' . $_CB_database->NameQuote( $this->attributes( 'value' ) );
					}

					if ( $joinKey ) {
						$joinsSQL[]					=	$joinType . ' JOIN ' . $_CB_database->NameQuote( $table ) . ' AS ' . $joinKey . ' ON ' . $condition;
						$condition					=	$joinKey . '.' . $_CB_database->NameQuote( $this->attributes( 'name' ) );
						if ( $prevJoinKey ) {
							$tableReferences[$table]	=	$prevJoinKey;
						} else {
							unset( $tableReferences[$table] );
						}
					}
				}
				break;

			case 'joinkeys':
				if ( count( $subFormulas ) > 0 ) {
					$condition				=	'(' . implode( ') ' . $this->attributes( 'operator' ) . ' (', $subFormulas ) . ')';
				}
				break;

			case 'json':
				$count						=	count( $subFormulas );
				if ( $count > 1 ) {
					$condition				=	'(' . implode( ' ' . $this->attributes( 'operator' ) . ' ', $subFormulas ) . ')';
				}
				elseif ( $count == 1 ) {
					$condition				=	implode( $subFormulas );
				}
				break;

			case 'column':
			case 'where':
				switch ( $this->attributes( 'type' ) ) {
					case 'sql:formula':
						$condition			=	$this->attributes( 'value' );
						break;

					case 'sql:operator':
						$count				=	count( $subFormulas );
						if ( $count > 1 ) {
							$condition		=	'(' . implode( ' ' . $this->attributes( 'operator' ) . ' ', $subFormulas ) . ')';
						}
						elseif ( $count == 1 ) {
							$condition		=	implode( $subFormulas );
						}
						break;

					case 'sql:function':
						$condition			=	$this->attributes( 'operator' ) . '( ' . implode( ', ', $subFormulas ) . ' )';
						break;

					case 'sql:field':
						if ( isset( $tableReferences[$this->attributes( 'table' )] ) ) {
							$operator		=	$this->attributes( 'operator' );
							$value			=	$this->attributes( 'value' );
							$valuetype		=	$this->attributes( 'valuetype' );
							$searchmode		=	$this->attributes( 'searchmode' );

							if ( in_array( $operator, array( '=', '<>', '!=' ) ) && ( $valuetype == 'const:string' ) ) {
								switch ( $searchmode ) {
									case 'all':
									case 'any':
									case 'anyis':
									case 'phrase':
									case 'allnot':
									case 'anynot':
									case 'anyisnot':
									case 'phrasenot':
										$precise				=	in_array( $searchmode, array( 'anyis', 'anyisnot' ) );

										if ( $replaceWildcards && ! $precise ) {
											$this->_replaceWildCards( $operator, $value );		// changes $operator and $value !
										}
										if ( is_array( $value ) ) {
											$eachValues			=	$value;
										} else {
											if ( cbStartOfStringMatch( $searchmode, 'phrase' ) ) {
												$eachValues		=	array( $value );
											} else {
												global $_CB_framework;
												if ( $_CB_framework->outputCharset() == 'UTF-8' ) {
													$eachValues	=	@preg_split( '/\p{Z}+/u', $value );

													if ( preg_last_error() == PREG_INTERNAL_ERROR ) {
														// PCRE has not been compiled with utf-8 support, do our best:
														$eachValues	=	preg_split( '/\W+/', $value );
													}
												} else {
													$eachValues	=	preg_split( '/\W+/', $value );
												}
											}
										}
										$conditions				=	array();

										foreach ( $eachValues as $v ) {
											if ( $v != '' ) {
												if ( ! ( $precise || in_array( $operator, array( 'LIKE', 'NOT LIKE' ) ) ) ) {
													$operator	=	$this->_operatorToLike( $operator );
												}
												$conditions[]	=	$this->_buildop( $operator, ( $precise ? $v : $this->_prepostfixPercent( $v ) ), $valuetype, $tableReferences );
											}
										}

										if ( count( $conditions ) > 1 ) {
											$op					=	( in_array( $searchmode, array( 'all', 'allnot' ) ) ? ') AND (' : ') OR (' );
											$condition			=	'((' . implode( $op, $conditions ) . '))';
										} elseif ( count( $conditions ) == 1 ) {
											$condition			=	implode( '', $conditions );
										} else {
											$condition			=	null;
										}

										if ( in_array( $searchmode, array( 'allnot', 'anynot', 'anyisnot', 'phrasenot' ) ) && $condition ) {
											$condition			=	'NOT(' . $condition . ')';
										}
										break;

									case 'isnot':
										$operator				=	( $operator == '=' ? '<>' : '=' );
										$condition				=	$this->_buildop( $operator, $value, $valuetype, $tableReferences );
										break;

									case 'is':
									default:
										$condition				=	$this->_buildop( $operator, $value, $valuetype, $tableReferences );
										break;

								}
							} else {
								$condition						=	$this->_buildop( $operator, $value, $valuetype, $tableReferences );
							}
						}
						break;
					default:
						break;
				}
				break;
			default:
				break;
		}
		return $condition;
	}

	/**
	 * Replaces wildcards * into SQL's % and adds them
	 * @param  string  $operator  IN+OUT: Input: '=', '<>' or '!=', OUTPUT: 'LIKE' or 'NOT LIKE'
	 * @param  string  $value     IN+OUT: Value to search, INPUT: with *, OUTPUT: %+sql-search-escaped
	 * @return boolean
	 */
	protected function _replaceWildCards( &$operator, &$value )
	{
		$changes				=	false;

		if ( is_array( $value ) ) {
			foreach ( array_keys( $value ) as $k ) {
				$changes		=	$this->_replaceWildCards( $operator, $value[$k] ) || $changes;
			}
		} else {
			$escSearch			=	str_replace( '|*|', '|`|', $value );

			if ( strpos( $escSearch, '*' ) !== false ) {
				$escSearch		=	Application::Database()->getEscaped( $escSearch, true );
				$escSearch		=	str_replace( '*', '%', $escSearch );
				$value			=	str_replace( '|`|', '|*|', $escSearch );
				$operator		=	$this->_operatorToLike( $operator );
				$changes		=	true;
			}
		}

		return $changes;
	}

	/**
	 * Returns string with added '%' before and after if not already there
	 *
	 * @param  string  $sqlSearchEscaped
	 * @return string
	 */
	protected function _prepostfixPercent( $sqlSearchEscaped )
	{
		if ( $sqlSearchEscaped[0] != '%' ) {
			$sqlSearchEscaped	=	'%' . $sqlSearchEscaped;
		}

		if ( $sqlSearchEscaped[strlen($sqlSearchEscaped) - 1] != '%' ) {
			$sqlSearchEscaped	.=	'%';
		}

		return $sqlSearchEscaped;
	}

	/**
	 * Replaces = with LIKE and '<>' and '!=' with 'NOT LIKE'
	 *
	 * @param  string  $operator
	 * @return string
	 */
	protected function _operatorToLike( $operator )
	{
		switch ( $operator ) {
			case '<>':
			case '!=':
				$operator	=	'NOT LIKE';
				break;

			case '=':
			default:
				$operator	=	'LIKE';
				break;
		}

		return $operator;
	}

	/**
	 * Builds a SQL query VALUE OPERATOR VALUE
	 * With valuetype for VALUE and using table references.
	 *
	 * @param  string    $operator
	 * @param  string    $value
	 * @param  string    $valuetype
	 * @param  array     $tableReferences
	 * @return string
	 */
	protected function _buildop( $operator, $value, $valuetype, &$tableReferences )
	{
		global $_CB_database;

		$column			=	$tableReferences[$this->attributes( 'table' )] . '.' . $_CB_database->NameQuote( $this->attributes( 'name' ) );

		if ( $this->_json ) {
			// This node is a part of a JSON root node so lets try to find its JSON path:
			$path		=	$this->attributes( 'name' );

			if ( $this->_json->paths && isset( $this->_json->paths[$path] ) ) {
				$path	=	$this->_json->paths[$path];
			} elseif ( $this->paths && isset( $this->paths[$path] ) ) {
				$path	=	$this->paths[$path];
			}

			// JSON isn't supported so lets at least point to the column the JSON is stored in:
			$column		=	$tableReferences[$this->_json->attributes( 'table' )] . '.' . $_CB_database->NameQuote( $this->_json->attributes( 'name' ) );

			if ( $_CB_database->versionCompare( '5.7.8' ) ) {
				if ( is_string( $value ) ) {
					$value		=	cbutf8_strtolower( $value );
				}

				if ( ( strpos( $path, '*' ) !== false ) && in_array( $operator, array( '=', '!=', '<>', 'LIKE', 'NOT LIKE' ) ) ) {
					// We're a simple search and the path contains a wildcard so lets utilize JSON_SEARCH instead:
					$value		=	( $valuetype == 'sql:field' ? ( isset( $tableReferences[$this->attributes( 'valuetable' )] ) ? $tableReferences[$this->attributes( 'valuetable' )] . '.' : '' ) : '' )
									.	$this->_sqlCleanQuote( $value, $valuetype );

					return "JSON_SEARCH( LOWER( $column ), 'one', $value, NULL, " . $_CB_database->Quote( $path ) . " )"
							. ( in_array( $operator, array( '=', 'LIKE' ) ) ? " IS NOT NULL" : " IS NULL" );
				} else {
					// JSON is supported so lets perform the extraction of the value based off the JSON path:
					$column		=	'LOWER( JSON_EXTRACT( ' . $column . ', ' . $_CB_database->Quote( $path ) . ' ) )';
				}
			}
		}

		return	$column
				.	' ' . $operator . ' '
				.	( $valuetype == 'sql:field' ? ( isset( $tableReferences[$this->attributes( 'valuetable' )] ) ? $tableReferences[$this->attributes( 'valuetable' )] . '.' : '' ) : '' )
				.	$this->_sqlCleanQuote( $value, $valuetype );
	}

	/**
	 * Cleans and makes a value SQL safe depending on the type that is enforced.
	 *
	 * @param  mixed   $fieldValue
	 * @param  string  $type
	 * @return string
	 */
	protected function _sqlCleanQuote( $fieldValue, $type )
	{
		global $_CB_database;

		$typeArray		=	explode( ':', $type, 3 );

		if ( count( $typeArray ) < 2 ) {
			$typeArray	=	array( 'const' , $type );
		}

		switch ( $typeArray[1] ) {
			case 'int':
				$value		=	(int) $fieldValue;
				break;
			case 'float':
				$value		=	(float) $fieldValue;
				break;
			case 'formula':
				$value		=	$fieldValue;
				break;
			case 'field':						// this is temporarly handled here
				$value		=	$_CB_database->NameQuote( $fieldValue );
				break;
			case 'datetime':
				if ( preg_match( '/[0-9]{4}-[01][0-9]-[0-3][0-9] [0-2][0-9](:[0-5][0-9]){2}/', $fieldValue ) ) {
					$value	=	$_CB_database->Quote( $fieldValue );
				} else {
					$value	=	"''";
				}
				break;
			case 'date':
				if ( preg_match( '/[0-9]{4}-[01][0-9]-[0-3][0-9]/', $fieldValue ) ) {
					$value	=	$_CB_database->Quote( $fieldValue );
				} else {
					$value	=	"''";
				}
				break;
			case 'time':
				if ( preg_match( '/-?[0-9]{1,3}(:[0-5][0-9]){2}/', $fieldValue ) ) {
					$value	=	$_CB_database->Quote( $fieldValue );
				} else {
					$value	=	"''";
				}
				break;
			case 'string':
				$value		=	$_CB_database->Quote( $fieldValue );
				break;
			case 'null':
				if ( $fieldValue != 'NULL' ) {
					trigger_error( sprintf( 'cbSqlQueryPart::_sqlCleanQuote: ERROR: field type sql:null has not NULL value' ) );
				}
				$value		=	'NULL';
				break;

			default:
				trigger_error( 'cbSqlQueryPart::_sqlQuoteValueType: ERROR_UNKNOWN_TYPE: ' . htmlspecialchars( $type ), E_USER_NOTICE );
				$value		=	$_CB_database->Quote( $fieldValue );	// false;
				break;
		}

		return (string) $value;
	}

	/**
	 * Returns the name of the tag of $this
	 *
	 * @return string
	 */
	protected function getName()
	{
		return $this->tag;
	}

	/**
	 * Returns an attribut $name if exists, otherwise NULL
	 *
	 * @param  string|null   $name
	 * @return string|null
	 */
	protected function attributes( $name = null )
	{
		if ( isset( $this->$name ) ) {
			return $this->$name;
		}

		return null;
	}

	/**
	 * Returns an array of all children
	 *
	 * @return cbSqlQueryPart[]
	 */
	protected function children( )
	{
		return $this->_children;
	}
}

Anon7 - 2022
AnonSec Team