__  __    __   __  _____      _            _          _____ _          _ _ 
 |  \/  |   \ \ / / |  __ \    (_)          | |        / ____| |        | | |
 | \  / |_ __\ V /  | |__) | __ ___   ____ _| |_ ___  | (___ | |__   ___| | |
 | |\/| | '__|> <   |  ___/ '__| \ \ / / _` | __/ _ \  \___ \| '_ \ / _ \ | |
 | |  | | |_ / . \  | |   | |  | |\ V / (_| | ||  __/  ____) | | | |  __/ | |
 |_|  |_|_(_)_/ \_\ |_|   |_|  |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1
 if you need WebShell for Seo everyday contact me on Telegram
 Telegram Address : @jackleet
        
        
For_More_Tools: Telegram: @jackleet | Bulk Smtp support mail sender | Business Mail Collector | Mail Bouncer All Mail | Bulk Office Mail Validator | Html Letter private



Upload:

Command:

[email protected]: ~ $
<?php
/**
 * CustomTables Joomla! 3.x/4.x/5.x Component
 * @package Custom Tables
 * @author Ivan Komlev <[email protected]>
 * @link https://joomlaboat.com
 * @copyright (C) 2018-2024. Ivan Komlev
 * @license GNU/GPL Version 2 or later - https://www.gnu.org/licenses/gpl-2.0.html
 **/

// no direct access
defined('_JEXEC') or die();

use CustomTables\common;
use CustomTables\CT;
use CustomTables\CTMiscHelper;
use CustomTables\database;
use CustomTables\Fields;
use CustomTables\Filtering;
use CustomTables\CustomPHP\CleanExecute;
use CustomTables\MySQLWhereClause;
use CustomTables\record;
use CustomTables\TwigProcessor;
use CustomTables\SaveFieldQuerySet;

use Joomla\CMS\Factory;
use Joomla\CMS\MVC\Model\BaseDatabaseModel;

$siteLibPath = CUSTOMTABLES_LIBRARIES_PATH . DIRECTORY_SEPARATOR;
require_once($siteLibPath . 'layout.php');

$libPath = CUSTOMTABLES_LIBRARIES_PATH . DIRECTORY_SEPARATOR . 'tagprocessor' . DIRECTORY_SEPARATOR;
require_once($libPath . 'valuetags.php');


class CustomTablesModelEditItem extends BaseDatabaseModel
{
	var CT $ct;
	var bool $userIdField_Unique;
	var bool $userIdField_UniqueUsers;
	var ?string $listing_id;
	var bool $isAuthorized;
	var ?array $row;

	function __construct()
	{
		$this->userIdField_Unique = false;
		$this->userIdField_UniqueUsers = false;
		parent::__construct();
	}

	/**
	 * @throws Exception
	 * @since 3.2.2
	 */
	function CheckAuthorizationACL($access): bool
	{
		$this->isAuthorized = false;

		if ($access == 'core.edit' and $this->listing_id == 0)
			$access = 'core.create'; //add new

		if ($this->ct->Env->user->authorise($access, 'com_customtables')) {
			$this->isAuthorized = true;
			return true;
		}

		if ($access != 'core.edit')
			return false;

		if ($this->ct->Params->userIdField != '') {
			if ($this->ct->checkIfItemBelongsToUser($this->listing_id, $this->ct->Params->userIdField)) {
				if ($this->ct->Env->user->authorise('core.edit.own', 'com_customtables')) {
					$this->isAuthorized = true;
					return true;
				} else
					$this->isAuthorized = false;
			}
		}
		return false;
	}

	/**
	 * @throws Exception
	 * @since 3.2.3
	 */
	function copy(&$msg, &$link): bool
	{
		$listing_id = common::inputGetCmd('listing_id');
		if ($listing_id === null)
			return false;

		try {
			$whereClause = new MySQLWhereClause();
			$whereClause->addCondition($this->ct->Table->realidfieldname, $listing_id);
			$rows = database::loadAssocList($this->ct->Table->realtablename, ['*'], $whereClause, null, null, 1);
		} catch (Exception $e) {
			$this->ct->errors[] = $e->getMessage();
			$msg = $e->getMessage();
			return false;
		}

		if (count($rows) == 0) {
			$msg = 'Record not found or something went wrong.';
			return false;
		}

		$newRow = $rows[0];
		$newRow[$this->ct->Table->realidfieldname] = null;
		$new_listing_id = database::insert($this->ct->Table->realtablename, $newRow);

		return $this->store($link, true, $new_listing_id);
	}

	/**
	 * @throws Exception
	 * @since 3.2.3
	 */
	function store(string &$link, bool $isCopy = false, string $listing_id = null): bool
	{
		$record = new record($this->ct);

		//IP Filter
		$USER_IP = SaveFieldQuerySet::getUserIP();

		$IP_Black_List = array();

		if (in_array($USER_IP, $IP_Black_List))
			return false;

		$record->editForm->load();//Load Menu Item parameters

		if ($record->save($listing_id, $isCopy)) {
			$this->listing_id = $record->listing_id;

			//Prepare "Accept Return To" Link
			$return2Link = common::getReturnToURL();

			//Refresh menu if needed
			if ($this->ct->Params->msgItemIsSaved !== null and $this->ct->Params->msgItemIsSaved != "") {
				$this->ct->messages[] = $this->ct->Params->msgItemIsSaved;
			}

			if ($this->ct->Env->advancedTagProcessor) {

				try {
					CleanExecute::executeCustomPHPfile($this->ct->Table->tablerow['customphp'], $record->row_new, $record->row_old);
				} catch (Exception $e) {
					$this->ct->errors[] = 'Custom PHP file: ' . $this->ct->Table->tablerow['customphp'] . ' (' . $e->getMessage() . ')';
				}
				$return2Link_Updated = common::getReturnToURL();
				if ($return2Link != $return2Link_Updated)
					$link = $return2Link_Updated;
			}

			if ($this->listing_id !== null)
				common::inputSet("listing_id", $this->listing_id);

			return true;
		} else {
			return false;
		}
	}

	/**
	 * @throws Exception
	 * @since 3.2.2
	 */
	function load(CT $ct): bool
	{
		$this->ct = $ct;
		$this->ct->getTable($ct->Params->tableName, $this->ct->Params->userIdField);

		if ($this->ct->Table->tablename === null) {
			$this->ct->errors[] = 'Table not selected (61).';
			return false;
		}

		$this->ct->Params->userIdField = $this->findUserIDField($this->ct->Params->userIdField);//to make sure that the field name is real and two userid fields can be used

		if (is_null($ct->Params->msgItemIsSaved))
			$ct->Params->msgItemIsSaved = common::translate('COM_CUSTOMTABLES_RECORD_SAVED');

		$this->listing_id = $this->ct->Params->listing_id;

		//Load the record
		$app = Factory::getApplication();
		$menu = $app->getMenu();
		$currentMenuItem = $menu->getActive();

		if ($currentMenuItem and $currentMenuItem->query['view'] == 'edititem')
			$this->listing_id = $this->processCustomListingID();

		if (($this->listing_id === null or $this->listing_id == '' or $this->listing_id == 0) and $this->userIdField_UniqueUsers and $this->ct->Params->userIdField != '') {
			//try to find record by userid and load it
			$this->listing_id = $this->findRecordByUserID();
		}

		$this->ct->Params->listing_id = $this->listing_id;
		return true;
	}

	function findUserIDField($userIdField): string
	{
		if ($userIdField != '') {
			$userIdFields = array();
			$statement_items = common::ExplodeSmartParams($userIdField); //"and" and "or" as separators

			foreach ($statement_items as $item) {
				if ($item[0] == 'or' or $item[0] == 'and') {
					$field = $item[1];
					if (!str_contains($field, '.')) {
						//Current table field name
						//find selected field
						foreach ($this->ct->Table->fields as $fieldrow) {
							if ($fieldrow['fieldname'] == $field and ($fieldrow['type'] == 'userid' or $fieldrow['type'] == 'user')) {
								$userIdFields[] = [$item[0], $item[1]];

								//Following apply to current table fields only and to only one (the last one in the statement)
								$params = $fieldrow['typeparams'];
								$parts = CTMiscHelper::csv_explode(',', $params);

								$this->userIdField_UniqueUsers = false;
								if (isset($parts[4]) and $parts[4] == 'unique')
									$this->userIdField_UniqueUsers = true;

								break;
							}
						}
					} else {
						//Table join
						//parents(children).user
						$userIdFields[] = [$item[0], $item[1]];
					}
				}
			}

			$userIdFieldsStr = '';
			$index = 0;
			foreach ($userIdFields as $field) {
				if ($index == 0)
					$userIdFieldsStr .= $field[1];
				else
					$userIdFieldsStr .= ' ' . $field[0] . ' ' . $field[1];

				$index += 1;
			}
			return $userIdFieldsStr;
		}
		return '';
	}

	/**
	 * @throws Exception
	 * @since 3.2.2
	 */
	function processCustomListingID(): ?int
	{
		if ($this->listing_id !== null and (is_numeric($this->listing_id) or (!str_contains($this->listing_id, '=') and !str_contains($this->listing_id, '<') and !str_contains($this->listing_id, '>')))) {
			try {
				$whereClause = new MySQLWhereClause();
				$whereClause->addCondition($this->ct->Table->realidfieldname, $this->listing_id);

				$rows = database::loadAssocList($this->ct->Table->realtablename, $this->ct->Table->selects, $whereClause, null, null, 1);
			} catch (Exception $e) {
				$this->ct->errors[] = $e->getMessage();
				return null;
			}

			if (count($rows) < 1)
				return null;

			return $this->listing_id;
		}

		$filter = $this->ct->Params->filter;

		if ($filter == '')
			return null;

		if ($this->ct->Env->legacySupport) {
			$LayoutProc = new LayoutProcessor($this->ct);
			$LayoutProc->layout = $filter;
			$filter = $LayoutProc->fillLayout(null, null, '[]', true);
		}

		$twig = new TwigProcessor($this->ct, $filter);
		$filter = $twig->process();

		if ($twig->errorMessage !== null)
			$this->ct->errors[] = $twig->errorMessage;

		//TODO
		$this->ct->errors[] = 'Filtering not done.';

		$filtering = new Filtering($this->ct, $this->ct->Params->showPublished);
		$filtering->addWhereExpression($filter);
		//$whereArray = $filtering->where;

		if ($this->ct->Table->published_field_found)
			$filtering->whereClause->addCondition('published', 1);
		//$whereArray[] = 'published=1';

		//$where = '';
		//if (count($filtering->whereClause->conditions) > 0) {
		//	$where = ' WHERE ' . $filtering->whereClause->getWhereClause();// implode(" AND ", $whereArray);
		//}

		//$query = 'SELECT ' . $this->ct->Table->realidfieldname . ' FROM ' . $this->ct->Table->realtablename . ' ' . $where;

		//$query .= ' ORDER BY ' . $this->ct->Table->realidfieldname . ' DESC'; //show last
		//$query .= ' LIMIT 1';

		try {
			$rows = database::loadAssocList($this->ct->Table->realtablename, [$this->ct->Table->realidfieldname], $filtering->whereClause, $this->ct->Table->realidfieldname, 'DESC', 1);
		} catch (Exception $e) {
			$this->ct->errors[] = $e->getMessage();
			return null;
		}

		if (count($rows) < 1)
			return null;

		$this->listing_id = $rows[0][$this->ct->Table->realidfieldname];
		return $this->listing_id;
	}

	/**
	 * @throws Exception
	 * @since 3.2.3
	 */
	function findRecordByUserID(): ?string
	{
		//$wheres = array();
		$whereClause = new MySQLWhereClause();

		if ($this->ct->Table->published_field_found)
			$whereClause->addCondition('published', 1);
		//$wheres[] = 'published=1';

		$whereClauseUser = $this->ct->UserIDField_BuildWheres($this->ct->Params->userIdField, $this->listing_id);
		$whereClause->addNestedCondition($whereClauseUser);
		//$wheres = array_merge($wheres, $wheres_user);
		//$query = 'SELECT ' . implode(',', $this->ct->Table->selects) . ' FROM ' . $this->ct->Table->realtablename . ' WHERE ' . implode(' AND ', $wheres) . ' LIMIT 1';

		try {
			$rows = database::loadAssocList($this->ct->Table->realtablename, $this->ct->Table->selects, $whereClause, null, null, 1);
		} catch (Exception $e) {
			$this->ct->errors[] = $e->getMessage();
			return -1;
		}

		if (count($rows) < 1)
			return null;

		$row = $rows[0];
		return $row[$this->ct->Table->realidfieldname];
	}

	/**
	 * @throws Exception
	 * @since 3.2.4
	 */
	/*
	 *
	 * This method can be replaced with in layout return link variable
	 *
	function PrepareAcceptReturnToLink($link): ?string
	{

		if ($link == '')
			return '';

		//$query = 'SELECT ' . implode(',', $this->ct->Table->selects) . ' FROM ' . $this->ct->Table->realtablename . ' ORDER BY ' . $this->ct->Table->realidfieldname . ' DESC LIMIT 1';

		//try {
		$whereClause = new MySQLWhereClause();
		$rows = database::loadAssocList($this->ct->Table->realtablename, $this->ct->Table->selects, $whereClause, $this->ct->Table->realidfieldname, 'DESC', 1);

		//} catch (Exception $e) {
		//	$this->ct->errors[] = $e->getMessage();
		//	return false;
		//}

		if (count($rows) != 1) {
			$this->ct->errors[] = 'Record not saved';
			return false;
		}

		$row = $rows[0];

		if ($this->ct->Env->legacySupport) {
			require_once(CUSTOMTABLES_LIBRARIES_PATH . DIRECTORY_SEPARATOR . 'layout.php');
			$LayoutProc = new LayoutProcessor($this->ct);
			$LayoutProc->layout = $link;
			$link = $LayoutProc->fillLayout($row, "", '[]', true);
		}

		$twig = new TwigProcessor($this->ct, $link);
		try {
			$link = $twig->process($row);
			//$this->ct->errors[] = $twig->errorMessage;

		} catch (Exception $e) {
			$this->ct->errors[] = $e->getMessage();

			$link = '';
		}

		if ($twig->errorMessage !== null) {
			$this->ct->errors[] = $twig->errorMessage;
			$link = '';
		}
		return $link;
	}
	*/

	/*
	function CheckValueRule($prefix,$fieldname, $fieldType, $typeParams)
	{
		$valuearray=array();
		$value='';

		switch($fieldType)
			{
				case 'records':

					$typeParamsArrayy=explode(',',$typeParams);
					if(count($typeParamsArrayy)>2)
					{
						$esr_selector=$typeParamsArrayy[2];
						$selectorpair=explode(':',$esr_selector);

						switch($selectorpair[0])
						{
							case 'single';
									$value=common::inputPostString($prefix.$fieldname);
								break;

							case 'multi';
									$valuearray = common::inputGet( $prefix.$fieldname, array(), 'post', 'array' );
									$value='"'.implode('","',$valuearray).'"';
								break;
							case 'multibox';
									$valuearray = common::inputGet( $prefix.$fieldname, array(), 'post', 'array' );
									$value='"'.implode('","',$valuearray).'"';
								break;

							case 'radio';
									$value=common::inputPostString($prefix.$fieldname);
								break;

							case 'checkbox';
									$valuearray = common::inputGet( $prefix.$fieldname, array(), 'post', 'array' );
									$value='"'.implode('","',$valuearray).'"';
								break;
						}

					}

					break;
				case 'radio':
						$value=common::inputPostString($prefix.$fieldname);
					break;

				case 'googlemapcoordinates':
						$value=common::inputPostString($prefix.$fieldname);
					break;

				case 'string':
						$value=common::inputPostString($prefix.$fieldname);
					break;

				case 'multilangstring':

					$firstlanguage=true;
					foreach($this->ct->Languages->LanguageList as $lang)
					{
						if($firstlanguage)
						{
							$postfix='';
							$firstlanguage=false;
						}
						else
							$postfix='_'.$lang->sef;

						$valuearray[]=common::inputPostString($prefix.$fieldname.$postfix);

					}
					$value='"'.implode('","',$valuearray).'"';
					break;


				case 'text':
					$value = ComponentHelper::filterText(common::inputPost($prefix.$fieldname, '', 'raw'));
					break;

				case 'multilangtext':

					$firstlanguage=true;
					foreach($this->ct->Languages->LanguageList as $lang)
					{
						if($firstlanguage)
						{
							$postfix='';
							$firstlanguage=false;
						}
						else
							$postfix='_'.$lang->sef;

						$value_ = ComponentHelper::filterText(common::inputPost($prefix.$fieldname.$postfix, '', 'raw'));

						$valuearray[]=$value_;

					}
					$value='"'.implode('","',$valuearray).'"';
					break;

				case 'int':
						$value=common::inputPostInt($prefix.$fieldname,0);
					break;

				case 'user':
						$value=(int)common::inputPostInt($prefix.$fieldname,0);
					break;

				case 'float':
						$value=common::inputPostFloat($prefix.$fieldname,0,'FLOAT');
					break;


				case 'article':
						$value=common::inputPostInt($prefix.$fieldname,0);
					break;

				case 'multilangarticle':

					$firstlanguage=true;
					foreach($this->ct->Languages->LanguageList as $lang)
					{
						if($firstlanguage)
						{
							$postfix='';
							$firstlanguage=false;
						}
						else
							$postfix='_'.$lang->sef;

						$valuearray[]=common::inputPostInt($prefix.$fieldname.$postfix,0);

					}
					$value='"'.implode('","',$valuearray).'"';
					break;

				case 'email':
						$value=common::inputPostString($prefix.$fieldname);
					break;

				case 'checkbox':
						$value=common::inputPostCmd($prefix.$fieldname);
					break;

				case 'date':
						$value=common::inputPostString($prefix.$fieldname);
					break;
			}

		if($value=='')
			$value='""';

		return;
	}
	*/

	/**
	 * @throws Exception
	 * @since 3.2.2
	 */
	function Refresh($save_log = 1): int
	{
		$listing_ids_str = common::inputPostString('ids', '', 'create-edit-record');

		if ($listing_ids_str != '') {
			$listing_ids_ = explode(',', $listing_ids_str);
			foreach ($listing_ids_ as $listing_id) {
				if ($listing_id != '') {
					$listing_id = preg_replace("/[^a-zA-Z_\d-]/", "", $listing_id);
					if ($this->ct->RefreshSingleRecord($listing_id, $save_log) == -1)
						return -count($listing_ids_); //negative value means that there is an error
				}
			}
			return count($listing_ids_);
		}

		$listing_id = common::inputGetCmd('listing_id', 0);

		if ($listing_id == 0 or $listing_id == '')
			return 0;

		return $this->ct->RefreshSingleRecord($listing_id, $save_log);
	}

	/**
	 * @throws Exception
	 * @since 3.2.3
	 */
	function setPublishStatus($status): int
	{
		$listing_ids_str = common::inputPostString('ids', '', 'create-edit-record');
		if ($listing_ids_str != '') {
			$listing_ids_ = explode(',', $listing_ids_str);
			foreach ($listing_ids_ as $listing_id) {
				if ($listing_id != '') {
					$listing_id = preg_replace("/[^a-zA-Z_\d-]/", "", $listing_id);
					if ($this->ct->setPublishStatusSingleRecord($listing_id, $status) == -1)
						return -count($listing_ids_); //negative value means that there is an error
				}
			}
			return count($listing_ids_);
		}

		$listing_id = $this->listing_id;
		if ($listing_id == '' or $listing_id == 0)
			return 0;

		return $this->ct->setPublishStatusSingleRecord($listing_id, $status);
	}

	/**
	 * @throws Exception
	 * @since 3.2.2
	 */
	function delete(): int
	{
		$listing_ids_str = common::inputPostString('ids', '', 'create-edit-record');
		if ($listing_ids_str != '') {

			$listing_ids_ = explode(',', $listing_ids_str);
			foreach ($listing_ids_ as $listing_id) {
				if ($listing_id != '') {
					$listing_id = preg_replace("/[^a-zA-Z_\d-]/", "", $listing_id);
					if ($this->ct->deleteSingleRecord($listing_id) == -1)
						return -count($listing_ids_); //negative value means that there is an error
				}
			}
			return count($listing_ids_);
		}

		$listing_id = common::inputGetCmd('listing_id', 0);
		if ($listing_id == '' or $listing_id == 0)
			return 0;

		return $this->ct->deleteSingleRecord($listing_id);
	}

	/**
	 * @throws Exception
	 * @since 3.2.3
	 */
	public function copyContent($from, $to)
	{
		//Copy value from one cell to another (drag and drop functionality)
		$from_parts = explode('_', $from);
		$to_parts = explode('_', $to);

		$from_listing_id = $from_parts[0];
		$to_listing_id = $to_parts[0];

		$from_field = Fields::FieldRowByName($from_parts[1], $this->ct->Table->fields);
		$to_field = Fields::FieldRowByName($to_parts[1], $this->ct->Table->fields);

		if (!isset($from_field['type']))
			die(common::ctJsonEncode(['error' => 'From field not found.']));

		if (!isset($to_field['type']))
			die(common::ctJsonEncode(['error' => 'To field not found.']));

		$from_row = $this->ct->Table->loadRecord($from_listing_id);
		$to_row = $this->ct->Table->loadRecord($to_listing_id);

		$f = $from_field['type'];
		$t = $to_field['type'];

		$ok = true;

		if ($f != $t) {
			switch ($t) {
				case 'string':
					if (!($f == 'email' or $f == 'int' or $f == 'float' or $f == 'text'))
						$ok = false;
					break;

				default:
					$ok = false;
			}
		}

		if (!$ok)
			die(common::ctJsonEncode(['error' => 'Target and destination field types do not match.']));

		$new_value = '';

		switch ($to_field['type']) {
			case 'sqljoin':
				if ($to_row[$to_field['realfieldname']] !== '')
					die(common::ctJsonEncode(['error' => 'Target field type is the Table Join. Multiple values not allowed.']));

				break;

			case 'email':

				if ($to_row[$to_field['realfieldname']] !== '')
					die(common::ctJsonEncode(['error' => 'Target field type is an Email. Multiple values not allowed.']));

				break;

			case 'string':

				if (str_contains($to_row[$to_field['realfieldname']], $from_row[$from_field['realfieldname']]))
					die(common::ctJsonEncode(['error' => 'Target field already contains this value.']));

				$new_value = $to_row[$to_field['realfieldname']];
				if ($new_value != '')
					$new_value .= ',';

				$new_value .= $from_row[$from_field['realfieldname']];
				break;

			case 'records':

				$new_items = [''];
				$to_items = explode(',', $to_row[$to_field['realfieldname']]);

				foreach ($to_items as $item) {
					if ($item != '' and !in_array($item, $new_items))
						$new_items[] = $item;
				}

				$from_items = explode(',', $from_row[$from_field['realfieldname']]);

				foreach ($from_items as $item) {
					if ($item != '' and !in_array($item, $new_items))
						$new_items[] = $item;
				}

				$new_items[] = '';

				if (count($new_items) == count($to_items))
					die(common::ctJsonEncode(['error' => 'Target field already contains this value(s).']));

				$new_value = implode(',', $new_items);

				break;
		}

		if ($new_value != '') {

			$data = [
				$to_field['realfieldname'] => $new_value
			];
			$whereClauseUpdate = new MySQLWhereClause();
			$whereClauseUpdate->addCondition($this->ct->Table->realidfieldname, $to_listing_id);

			try {
				database::update($this->ct->Table->realtablename, $data, $whereClauseUpdate);
			} catch (Exception $e) {
				$this->ct->errors[] = $e->getMessage();
				return false;
			}
			return true;
		}
		return false;
	}
}

Filemanager

Name Type Size Permission Actions
catalog.php File 4.99 KB 0664
editfiles.php File 5.61 KB 0664
edititem.php File 20.94 KB 0664
editphotos.php File 11.26 KB 0664
index.html File 43 B 0664
Filemanager