Current Path :
/
home
/
develito
/
www
/
components
/
com_sobipro
/
opt
/
fields
/
Or
Select Your Path :
Upload File :
New :
File
Dir
//home/develito/www/components/com_sobipro/opt/fields/fieldtype.php
<?php /** * @package: SobiPro Component for Joomla! * * @author * Name: Sigrid Suski & Radek Suski, Sigsiu.NET GmbH * Email: sobi[at]sigsiu.net * Url: https://www.Sigsiu.NET * * @copyright Copyright (C) 2006 - 2020 Sigsiu.NET GmbH (https://www.sigsiu.net). All rights reserved. * @license GNU/GPL Version 3 * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation, and under the additional terms according section 7 of GPL v3. * See https://www.gnu.org/licenses/gpl.html and https://www.sigsiu.net/licenses. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. * * @created 10-Jan-2009 by Radek Suski * @modified 30 June 2020 by Sigrid Suski */ defined( 'SOBIPRO' ) || exit( 'Restricted access' ); use Sobi\Input\Input; SPLoader::loadClass( 'models.fields.interface' ); /** * Class SPFieldType */ class SPFieldType extends SPObject { /*** @var SPField */ private $_field = null; /*** @var array */ protected $_attr = []; /*** @var string */ protected $_selected = null; /*** @var string */ protected $dType = 'free_single_simple_data'; /*** @var string */ protected $_rdata = null; /*** @var string */ protected $cssClass = "inputbox"; /** @var bool */ protected $showLabel = true; /** @var bool */ protected $showEditLabel = true; /** @var array */ protected $sets = []; /*** @var bool */ protected $suggesting = true; /** * SPFieldType constructor. * * @param $field */ public function __construct( &$field ) { $this->_field =& $field; /* transform params from the basic object to the spec. field properties */ if ( is_array( $this->params ) && count( $this->params ) ) { foreach ( $this->params as $k => $v ) { // if ( property_exists( $this, $k ) ) { if ( isset( $this->$k ) ) { $this->$k = $v; } } } // $this->cssClass = $field->get( 'cssClass' ); // if ( !( $this->cssClass ) ) { // $this->cssClass = 'input-medium'; // } } /** * @param $data */ protected function setData( $data ) { $this->_rdata = $data; $this->_field->setRawData( $data ); } /** * @param string $val * * @return void */ public function setCSS( $val = 'spField' ) { $this->cssClass = $val; } /** * @param string $val * * @return void */ public function setSelected( $val ) { $this->_selected = $val; } /** * Proxy pattern * * @param string $method * @param array $args * * @return mixed * @throws SPException */ public function __call( $method, $args ) { if ( $this->_field && method_exists( $this->_field, $method ) ) { return call_user_func_array( [ $this->_field, $method ], $args ); } else { throw new SPException( SPLang::e( 'CALL_TO_UNDEFINED_METHOD_S', $method ) ); } } /** * @param string $var * @param mixed $val * * @return \SPObject|void */ public function & set( $var, $val ) { if ( isset( $this->$var ) ) { $this->$var = $val; } return $this; } /** * This function is used for the case that a field wasn't used for some reason while saving an entry * But it has to perform some operation * E.g. Category field is set to be administrative and isn't used * but it needs to pass the previously selected categories to the entry model * * @param SPEntry $entry * @param string $request * * @return bool * */ public function finaliseSave( $entry, $request = 'post' ) { return true; } /** * @param $values * @param bool $freeInput * * @return string * @throws SPException */ protected function rangeSearch( $values, $freeInput = false ) { $request[ 'from' ] = isset( $this->_selected[ 'from' ] ) ? (int) $this->_selected[ 'from' ] : ''; $request[ 'to' ] = isset( $this->_selected[ 'to' ] ) ? (int) $this->_selected[ 'to' ] : ''; if ( !( $freeInput ) ) { $values = str_replace( [ "\n", "\r", "\t" ], null, $values ); $values = explode( ',', $values ); $data = []; $data2 = []; if ( count( $values ) ) { foreach ( $values as $k => $v ) { $data[ '' ] = Sobi::Txt( 'SH.RANGE_FROM' ); $data2[ '' ] = Sobi::Txt( 'SH.RANGE_TO' ); $data[ preg_replace( '/[^\d\.\-]/', null, trim( $v ) ) ] = $v; $data2[ preg_replace( '/[^\d\.\-]/', null, trim( $v ) ) ] = $v; } } $from = SPHtml_Input::select( $this->nid . '[from]', $data, $request[ 'from' ], false, [ 'class' => $this->cssClass . ' ' . Sobi::Cfg( 'search.form_list_def_css', 'SPSearchSelect' ), 'size' => '1' ] ); $to = SPHtml_Input::select( $this->nid . '[to]', $data2, $request[ 'to' ], false, [ 'class' => $this->cssClass . ' ' . Sobi::Cfg( 'search.form_list_def_css', 'SPSearchSelect' ), 'size' => '1' ] ); } else { $from = SPHtml_Input::text( $this->nid . '[from]', $request[ 'from' ], [ 'size' => '1', 'placeholder' => Sobi::Txt( 'SH.RANGE_FROM' ) ] ); $to = SPHtml_Input::text( $this->nid . '[to]', $request[ 'to' ], [ 'size' => '1', 'placeholder' => Sobi::Txt( 'SH.RANGE_TO' ) ] ); } if ( $this->suffix ) { return '<div class="spSelectRangeFrom"><div class="input-group input-append">' . $from . '<span class="input-group-addon add-on">' . $this->suffix . '</span></div></div>' . '<div class="spSelectRangeTo"><div class="input-group input-append">' . $to . '<span class="input-group-addon add-on">' . $this->suffix . '</span></div></div>'; } else { return '<div class="spRangeFrom">' . $from . '</div><div class="spRangeTo">' . $to . '</div>'; } } /** * @param $request * @param $section * * @return array * @throws \Sobi\Error\Exception */ protected function searchForRange( &$request, $section ) { $sids = []; if ( $request[ 'from' ] || $request[ 'to' ] ) { /* from has to be lower than to */ if ( $request[ 'from' ] > $request[ 'to' ] ) { $h = $request[ 'from' ] ; $request[ 'from' ] = $request[ 'to' ]; $request[ 'to' ] = $h; } $request[ 'from' ] = isset( $request[ 'from' ] ) ? $request[ 'from' ] : SPC::NO_VALUE; $request[ 'to' ] = isset( $request[ 'to' ] ) ? $request[ 'to' ] : SPC::NO_VALUE; $request[ 'from' ] = strstr( $request[ 'from' ], '.' ) ? ( floatval( $request[ 'from' ] ) ) : (int) $request[ 'from' ]; $request[ 'to' ] = strstr( $request[ 'to' ], '.' ) ? ( floatval( $request[ 'to' ] ) ) : (int) $request[ 'to' ]; try { /* We do not need the enabled / copy check as all entries are being verified in the search controller anyway */ $sids = SPFactory::db() ->dselect( 'sid', 'spdb_field_data', [ 'fid' => $this->fid, /*'copy' => '0', 'enabled' => 1,*/ 'baseData' => $request, 'section' => $section ] ) ->loadResultArray(); } catch ( SPException $x ) { Sobi::Error( $this->name(), SPLang::e( 'CANNOT_SEARCH_DB_ERR', $x->getMessage() ), SPC::WARNING, 0, __LINE__, __FILE__ ); } } return $sids; } /** * Returns meta description. * * @return |null */ public function metaDesc() { return $this->addToMetaDesc ? $this->data() : null; } /** * */ public function cleanCss() { $css = explode( ' ', $this->cssClass ); if ( count( $css ) ) { $this->cssClass = implode( ' ', array_unique( $css ) ); } } /** * Returns meta keys. * * @return |null */ public function metaKeys() { return $this->addToMetaKeys ? $this->data() : null; } /** * Proxy pattern. * * @param $property * * @return mixed */ public function __get( $property ) { if ( !( isset( $this->$property ) ) && $this->_field ) { return $this->_field->get( $property ); } else { return $this->get( $property ); } } /** * @param $vals * * @return void */ public function save( &$vals ) { $this->_attr =& $vals; if ( !isset( $vals[ 'params' ] ) ) { $vals[ 'params' ] = []; } $attr = $this->getAttr(); $properties = []; if ( count( $attr ) ) { foreach ( $attr as $property ) { if ( $property == 'untranslatable' && $vals[ 'adminField' ] == -1 ) { $vals[ $property ] = 0; } $properties[ $property ] = isset( $vals[ $property ] ) ? ( $vals[ $property ] ) : null; } } $vals[ 'params' ] = $properties; } /** * @return array */ public function properties() { return $this->getAttr(); } /** * @return array */ protected function getAttr() { return [ 'itemprop' ]; } /** * @param $sid * * @throws \Sobi\Error\Exception */ public function approve( $sid ) { $db = SPFactory::db(); static $lang = null; if ( !( $lang ) ) { $lang = Sobi::Lang( false ); } try { $copy = $db ->select( 'COUNT( fid )', 'spdb_field_data', [ 'sid' => $sid, 'copy' => '1', 'fid' => $this->fid ] ) ->loadResult(); if ( $copy ) { /** * Fri, Apr 6, 2012 * Ok, this is tricky now. * Normally we have such situation: * User is adding an entry and flags are: * approved | copy | baseData * 0 | 1 | Org * When it's just being approved everything works just fine * Problem is when the admin is changing the data then after edit it looks like this * approved | copy | baseData * 0 | 1 | Org << org user data * 1 | 0 | Changed << data changed by the administrator * So in the normal way we'll delete the changed data and approve the old data * Therefore we have to check if the approved data is maybe newer than the non-approved copy */ $date = $db ->select( 'copy', 'spdb_field_data', [ 'sid' => $sid, 'fid' => $this->fid ], 'updatedTime.desc', 1 ) ->loadResult(); /** * If the copy flag of the newer version is 0 - then delete all non-approved versions * and this is our current version */ if ( $date == 0 ) { $db->delete( 'spdb_field_data', [ 'sid' => $sid, 'copy' => '1', 'fid' => $this->fid ] ); } else { $params = [ 'sid' => $sid, 'copy' => '1', 'fid' => $this->fid ]; /** * when we have good multilingual management * we can change it * for the moment if an entry is entered in i.e. de_DE * but the admin approves the entry in en_GB and the multilingual mode is enabled * in case it was a new entry - empty data is being displayed */ /** Mon, Sep 23, 2013 10:39:37 - I think is should always change the data in the current lang * Since 1.1 we have good multilingual management so it is probably this issue */ // if ( !( Sobi::Cfg( 'entry.approve_all_langs', true ) ) ) { // $params[ 'lang' ] = array( $lang, SPC::NO_VALUE ); // } $el = $db ->select( 'editLimit', 'spdb_field_data', $params ) ->loadResult(); $cParams = $params; /** we need to delete only the entries that have the copy flag set to 1 with the selected language */ $languages = $db ->select( 'lang', 'spdb_field_data', [ 'sid' => $sid, 'copy' => '1', 'fid' => $this->fid ] ) ->loadResultArray(); $cParams[ 'copy' ] = 0; if ( $languages[ 0 ] != '' ) { $cParams[ 'lang' ] = $languages; } $db->delete( 'spdb_field_data', $cParams ); $db->update( 'spdb_field_data', [ 'copy' => '0', 'editLimit' => $el ], $params ); } } } catch ( SPException $x ) { Sobi::Error( $this->name(), SPLang::e( 'CANNOT_GET_FIELDS_DATA_DB_ERR', $x->getMessage() ), SPC::ERROR, 500, __LINE__, __FILE__ ); } } /** * @param $sid * @param $state * * @throws \Sobi\Error\Exception */ public function changeState( $sid, $state ) { $db =& SPFactory::db(); try { $db->update( 'spdb_field_data', [ 'enabled' => $state ], [ 'sid' => $sid, 'fid' => $this->fid ] ); } catch ( SPException $x ) { Sobi::Error( $this->name(), SPLang::e( 'CANNOT_CHANGE_FIELD_STATE', $x->getMessage() ), SPC::ERROR, 500, __LINE__, __FILE__ ); } } /** * @param $data * @param $section * * @return bool */ public function searchString( $data, $section ) { return true; } /** * @param $request * @param $section * * @return bool */ public function searchData( $request, $section ) { return true; } /** * @param $data * @param $section * @param bool $startWith * * @return bool */ public function searchSuggest( $data, $section, $startWith = true ) { return false; } /** * @param $sid (entry id) * * @throws \Sobi\Error\Exception */ public function rejectChanges( $sid ) { static $deleted = []; if ( !( isset( $deleted[ $sid ] ) ) ) { $db =& SPFactory::db(); try { $db->delete( 'spdb_field_data', [ 'sid' => $sid, 'copy' => 1 ] ); } catch ( SPException $x ) { Sobi::Error( $this->name(), SPLang::e( 'CANNOT_DELETE_FIELD_DATA', $x->getMessage() ), SPC::WARNING, 0, __LINE__, __FILE__ ); } $deleted[ $sid ] = true; } } /** * @param $sid (entry id) * * @throws \Sobi\Error\Exception */ public function deleteData( $sid ) { static $deleted = []; if ( !( isset( $deleted[ $sid ] ) ) ) { $db =& SPFactory::db(); try { $db->delete( 'spdb_field_data', [ 'sid' => $sid ] ); } catch ( SPException $x ) { Sobi::Error( $this->name(), SPLang::e( 'CANNOT_DELETE_FIELD_DATA', $x->getMessage() ), SPC::WARNING, 0, __LINE__, __FILE__ ); } $deleted[ $sid ] = true; } } /** * @return bool */ protected function checkCopy() { return ( in_array( Input::Task(), [ 'entry.approve', 'entry.edit', 'entry.save', 'entry.submit' ] ) || ( Sobi::Can( 'entry.access.unapproved_any' ) ) || Sobi::Can( 'entry.manage.*' ) ); } /** * @param $file * * @return array * @throws SPException */ protected function parseOptsFile( $file ) { $p = 0; $group = null; $gid = null; $options = []; if ( is_array( $file ) && count( $file ) ) { foreach ( $file as $key => $value ) { if ( is_array( $value ) ) { if ( strstr( $key, ',' ) ) { $group = explode( ',', $key ); $gid = SPLang::nid( $group[ 0 ] ); $group = $group[ 1 ]; } else { $gid = SPLang::nid( $key, true, true ); $group = $key; } $options[] = [ 'id' => $gid, 'name' => $group, 'parent' => null, 'position' => ++$p ]; if ( is_array( $value ) && count( $value ) ) { foreach ( $value as $k => $v ) { if ( is_numeric( $k ) ) { $k = SPLang::nid( $v ); } $options[] = [ 'id' => SPLang::nid( $k ), 'name' => $v, 'parent' => $gid, 'position' => ++$p ]; } } } else { $group = null; $gid = null; $options[] = [ 'id' => SPLang::nid( $key ), 'name' => $value, 'parent' => null, 'position' => ++$p ]; } } } return $options; } /** * @param SPEntry $entry * @param string $request * * @return string */ public function validate( $entry, $request ) { return true; } /** * @param $val * * @return int */ public function return_bytes( $val ) { if ( empty( $val ) ) { return 0; } $val = trim( $val ); preg_match( '#([0-9]+)[\s]*([a-z]+)#i', $val, $matches ); $last = ''; if ( isset( $matches[ 2 ] ) ) { $last = $matches[ 2 ]; } if ( isset( $matches[ 1 ] ) ) { $val = (int) $matches[ 1 ]; } switch ( strtolower( $last ) ) { case 'g': case 'gb': $val *= 1024; case 'm': case 'mb': $val *= 1024; case 'k': case 'kb': $val *= 1024; } return (int) $val; } /** * called recursively from select and multi select fields while duplicating the field. * * @param $options * @param $fid * @param $lang * @param $defLang * * @throws SPException */ public function generateOptionsToSave( $options, &$values, $fid, $lang, $defLang ) { $duplicates = false; foreach ( $options as $i => $option ) { /* check for doubles */ foreach ( $options as $pos => $opt ) { if ( $i == $pos ) { continue; } if ( $option[ 'id' ] == $opt[ 'id' ] ) { $option[ 'id' ] = $option[ 'id' ] . '_' . substr( ( string ) microtime(), 2, 8 ) . rand( 1, 100 ); $duplicates = true; } $option[ 'position' ] = $i + 1; } if ( isset( $option[ 'label' ] ) ) { $option[ 'name' ] = $option[ 'label' ]; } $values[ 'optionsArray' ][] = [ 'fid' => $fid, 'optValue' => $option[ 'id' ], 'optPos' => $option[ 'position' ], 'optParent' => $option[ 'parent' ] ]; $values[ 'labelsArray' ][] = [ 'sKey' => $option[ 'id' ], 'sValue' => $option[ 'name' ], 'language' => $defLang, 'oType' => 'field_option', 'fid' => $fid ]; $values[ 'defaultLabelsArray' ][] = [ 'sKey' => $option[ 'id' ], 'sValue' => $option[ 'name' ], 'language' => $lang, 'oType' => 'field_option', 'fid' => $fid ]; if ( array_key_exists( 'options', $option ) && is_array( $option[ 'options' ] ) && count( $option[ 'options' ] ) ) { $this->generateOptionsToSave( $option[ 'options' ], $values, $fid, $lang, $defLang ); } } if ( $duplicates ) { SPFactory::message()->warning( 'FIELD_WARN_DUPLICATE_OPT_ID' ); } } /** * @return string * @throws SPException */ public function phpSettings() { $limit = ini_get( 'memory_limit' ); $postsize = ini_get( 'post_max_size' ); $uploadsize = ini_get( 'upload_max_filesize' ); $sizes = "<div class=\"alert alert-info\"><p>" . SPLang::e( 'PHP_SIZE_MEMORY', $limit ) . "</p><p>" . SPLang::e( 'PHP_UPLOAD_SIZE', $uploadsize ) . "</p><p>" . SPLang::e( 'PHP_POST_SIZE', $postsize ) . "</p></div>"; return $sizes; } /** * @return string * @throws SPException */ public function phpWarnings() { $messages = []; $limit = ini_get( 'memory_limit' ); $postsize = ini_get( 'post_max_size' ); $uploadsize = ini_get( 'upload_max_filesize' ); $memory_limit = $this->return_bytes( $limit ); if ( $memory_limit < ( 32 * 1024 * 1024 ) && $memory_limit != -1 ) { // 32MB $messages[] = [ 'message' => SPLang::e( 'PHP_WARNING_LOWMEMORYWARN' ), 'description' => SPLang::e( 'PHP_WARNING_LOWMEMORYDESC', '32M', '32M' ) ]; } else { if ( $memory_limit < ( 64 * 1024 * 1024 ) && $memory_limit != -1 ) { // 64MB $messages[] = [ 'message' => SPLang::e( 'PHP_WARNING_MEDMEMORYWARN' ), 'description' => SPLang::e( 'PHP_WARNING_MEDMEMORYDESC', '64M', '64M' ) ]; } } $post_max_size = $this->return_bytes( $postsize ); $upload_max_filesize = $this->return_bytes( $uploadsize ); if ( $post_max_size < $upload_max_filesize ) { $messages[] = [ 'message' => SPLang::e( 'PHP_WARNING_UPLOADBIGGERTHANPOST' ), 'description' => Sobi::Txt( 'PHP_WARNING_UPLOADBIGGERTHANPOSTDESC' ) ]; } if ( $post_max_size < ( 16 * 1024 * 1024 ) ) // 16MB { $messages[] = [ 'message' => SPLang::e( 'PHP_WARNING_SMALLPOSTSIZE' ), 'description' => SPLang::e( 'PHP_WARNING_SMALLPOSTSIZEDESC', '16M' ) ]; } if ( $upload_max_filesize < ( 16 * 1024 * 1024 ) ) // 16MB { $messages[] = [ 'message' => SPLang::e( 'PHP_WARNING_SMALLUPLOADSIZE' ), 'description' => SPLang::e( 'PHP_WARNING_SMALLUPLOADSIZEDESC', '16M' ) ]; } $warning = ""; if ( is_array( $messages ) && count( $messages ) ) { $warning = "<div class=\"alert alert-danger\">"; foreach ( $messages as $msg ) { $warning .= "<h4 class=\"distance-top-sm distance-bottom-xs\">" . $msg[ 'message' ] . "</h4><p>" . $msg[ 'description' ] . "</p>"; } $warning .= "</div>"; } return $warning; } }