-
Постов
254 -
Зарегистрирован
-
Посещение
-
Победитель дней
1
Тип контента
Профили
Загрузки
База знаний IPS Community Suite 4
База знаний IP.Board 3.x
Форумы
События
Магазин
Совместные покупки
Сообщения, опубликованные BlackShot
-
-
4 minutes ago, by_ix said:
разве что для принятия псевдоправил.
Хороший вопрос, и если я правильно понял, то это и есть ответ. Я хочу сделать это обязательным полем, тогда как форма не будет отправлена, если пользователь не установил флажок. Что-то вроде согласия с условиями обслуживания, понимаете?
-
2 minutes ago, Desti said:
I think this is very difficult to do.
Слишком много работы?
-
Я использую настраиваемые поля как для приложения под названием Application Forms, так и для Commerce.
Почти все настраиваемые поля имеют возможность установить их как обязательные поля, за исключением некоторых. В моем случае я хочу, чтобы «флажок» действовал как обязательное поле.
Я пошел в system > CustomField и отредактировал CustomField.php. Я смог показать параметр обязательного поля, но он просто не работает. Это просто визуально.
Spoiler$toggles = array(
//Added the following line:
'Checkbox' => array( 'pf_not_null', "{$form->id}_header_pfield_displayoptions" ),
'CheckboxSet' => array( 'pf_content', 'pf_not_null', 'pf_search_type_on_off', "{$form->id}_header_pfield_displayoptions" ),
'Codemirror' => array( 'pf_not_null', 'pf_max_input', "{$form->id}_header_pfield_displayoptions" ),
'Email' => array( 'pf_not_null', 'pf_max_input', 'pf_input_format', 'pf_search_type', "{$form->id}_header_pfield_displayoptions" ),
'Member' => array( 'pf_not_null', 'pf_multiple', "{$form->id}_header_pfield_displayoptions" ),
'Password' => array( 'pf_not_null', 'pf_max_input', 'pf_input_format', "{$form->id}_header_pfield_displayoptions" ),
'Select' => array( 'pf_not_null', 'pf_content', 'pf_multiple', 'pf_search_type_on_off', "{$form->id}_header_pfield_displayoptions" ),
'Tel' => array( 'pf_not_null', 'pf_max_input', 'pf_input_format', 'pf_search_type', "{$form->id}_header_pfield_displayoptions" ),
'Text' => array( 'pf_not_null', 'pf_max_input', 'pf_input_format', 'pf_search_type', "{$form->id}_header_pfield_displayoptions" ),
'TextArea' => array( 'pf_not_null', 'pf_max_input', 'pf_input_format', 'pf_search_type', "{$form->id}_header_pfield_displayoptions" ),
'Url' => array( 'pf_not_null', 'pf_max_input', 'pf_input_format', 'pf_search_type', "{$form->id}_header_pfield_displayoptions" ),
'Radio' => array( 'pf_content', "{$form->id}_header_pfield_displayoptions", 'pf_search_type_on_off' ),
'Address' => array( 'pf_not_null', "{$form->id}_header_pfield_displayoptions" ),
'Color' => array( 'pf_not_null', "{$form->id}_header_pfield_displayoptions" ),
'Date' => array( 'pf_not_null', "{$form->id}_header_pfield_displayoptions" ),
'Editor' => array( 'pf_not_null', "{$form->id}_header_pfield_displayoptions", 'pf_search_type', 'pf_allow_attachments' ),
'Number' => array( 'pf_not_null', "{$form->id}_header_pfield_displayoptions"),
'Poll' => array( 'pf_not_null' ),
'Rating' => array( 'pf_not_null', "{$form->id}_header_pfield_displayoptions" ),
'Upload' => array( 'pf_not_null', "{$form->id}_header_pfield_displayoptions" ),
);Я также пошел в system > Helpers > Form > Checkbox.php, но я понятия не имею, что там редактировать. 😅
-
20 minutes ago, Desti said:
search
if ( $values = $form->values() ) { $this->form->handleForm( $values);
in modules/front/form.php and add change it to
if ( $values = $form->values() ) { unset ( $values['captcha_field'] ); $this->form->handleForm( $values);
Jesus Christ, that's magic Desti! I had spent so many hours trying to make this work - still can't believe I only needed such a short line of code. 😅
If you have time for it, I'm a bit curious. I know "unset" unsets local variables, but what does it do - in practice - with the code we edited? How did you figure that was the issue and where to find the right place to put it into? Did you just search for "values ="?
At least I'm happy I was able to figure where to add the Captcha code correctly. 😂 -
12 minutes ago, Desti said:
$form = new \IPS\Helpers\Form; $form->add( new \IPS\Helpers\Form\Text( 'text', '', FALSE, array( 'maxLength' => 14 ), NULL, NULL, NULL, 'text' ) ); $form->add( new \IPS\Helpers\Form\Captcha ); if ( $values = $form->values() ) { var_dump($values["captcha_field"]); die; // code execute only if captcha correct ( show "bool(true)" ). } \IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('view')->form( $form ); // simple template {$form|raw}
Everything works fine. Most likely you forgot handler ( if ( $values=...)
That's probably the culprit then (the handler). So I'm assuming I'm inserting the Captcha part into the wrong function? Because, without it, everything works just fine.
Here's the complete file without the Captcha part. I was inserting it into 'public function get_form()' because that's what seems to create the submit button:
https://pastebin.com/AVWswcLm or:
Spoiler<?php
namespace IPS\applicationform;
use IPS\applicationform\Helper\Notification;
use IPS\Helpers\Form\DateRange;
use IPS\Helpers\Form\Number;
use IPS\Helpers\Form\Text;
use IPS\Helpers\Form\YesNo;
use IPS\Member;if (!\defined('\IPS\SUITE_UNIQUE_KEY')) {
header((isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0') . ' 403 Forbidden');
exit;
}
class _Position extends \IPS\Node\Model implements
\IPS\Node\Permissions
{
protected static $multitons;
public static $databaseTable = 'applicationform_position';
public static $nodeTitle = 'application_position';public static $subnodeClass = 'IPS\applicationform\Position\Field';
public static $titleLangPrefix = 'applicationform_position_';
public static $descriptionLangSuffix = '_desc';
public static $databaseColumnOrder = "position";
protected $_url = NULL;
public static $seoTitleColumn = 'name_seo';
public static $urlBase = 'app=applicationform&module=applications&controller=form&id=';
public static $urlTemplate = 'application_form';public static $bitOptions = [
'options' => [
'options' => [
'bw_open_poll' => 1,
'bw_apply_only_once' => 2,
'bw_create_topic' => 4,
'bw_log_data' => 8, // deprecated, TODO remove in 2.2
'bw_vertical' => 16,
'bw_create_topic_reply' => 32,
'bw_create_pm' => 64,
'bw_create_post' => 128,
'bw_show_on_index' => 256,
'bw_show_in_modcp' => 512,
'bw_replace_topic_form' => 1024,
'bw_public_poll' => 2048
]
]
];
protected static $restrictions = array(
'app' => 'applicationform',
'module' => 'forms',
'all' => 'position_manage'
);/**
* @brief [Node] App for permission index
*/
public static $permApp = 'applicationform';/**
* @brief [Node] Type for permission index
*/
public static $permType = 'form';/**
* @brief The map of permission columns
*/
public static $permissionMap = array(
'view' => 'view',
'reply' => 2,
'manage' => 3,
);protected $dataToLog = array();
/**
* @brief [Node] Prefix string that is automatically prepended to permission matrix language strings
*/
public static $permissionLangPrefix = 'appformperm_';
/**
* Get SEO name
*
* @return string
*/
public function get_name_seo()
{
if( !$this->_data['name_seo'] )
{
$this->name_seo = \IPS\Http\Url\Friendly::seoTitle( \IPS\Lang::load( \IPS\Lang::defaultLanguage() )->get( 'applicationform_position_' . $this->id ) );
$this->save();
}return $this->_data['name_seo'] ?: \IPS\Http\Url\Friendly::seoTitle( \IPS\Lang::load( \IPS\Lang::defaultLanguage() )->get( 'applicationform_position_' . $this->id ) );
}protected function get_instructions()
{
if ( static::$titleLangPrefix and Member::loggedIn()->language()->checkKeyExists( static::$titleLangPrefix . $this->id . '_instructions') )
{
return \IPS\Member::loggedIn()->language()->addToStack( static::$titleLangPrefix . $this->id . '_instructions' );
}
return NULL;
}protected function get_submitmsg()
{
if ( static::$titleLangPrefix and Member::loggedIn()->language()->checkKeyExists( static::$titleLangPrefix . $this->id . '_submitmsg') )
{
return \IPS\Member::loggedIn()->language()->addToStack( static::$titleLangPrefix . $this->id . '_submitmsg' );
}
return \IPS\Member::loggedIn()->language()->addToStack("submitted" );
}public function get_showOnIndex()
{
return $this->options['bw_show_on_index'];
}public function get_showInModcp()
{
return $this->options['bw_show_in_modcp'];
}public function form(&$form)
{
$groups = [];
foreach ( \IPS\Member\Group::groups() as $group )
{
$groups[ $group->g_id ] = $group->name;
}
unset( $groups[ \IPS\Settings::i()->guest_group ] );$form->addTab( 'application_form' );
$form->add( new \IPS\Helpers\Form\Translatable( 'position_name', NULL, TRUE, array( 'app' => 'applicationform', 'key' => ( $this->id ? "applicationform_position_{$this->id}" : NULL ) ) ) );$form->add( new \IPS\Helpers\Form\Upload( 'position_icon', $this->icon ? \IPS\File::get( 'applicationform_Icons', $this->icon ) : NULL, FALSE, array( 'image' => TRUE, 'storageExtension' => 'applicationform_Icons' ), NULL, NULL, NULL, 'position_icon' ) );
$form->add( new \IPS\Helpers\Form\YesNo( 'position_bw_show_on_index', $this->id ? $this->options['bw_show_on_index'] : TRUE , FALSE ) );
$form->add( new \IPS\Helpers\Form\YesNo( 'position_bw_show_in_modcp', $this->id ? $this->options['bw_show_in_modcp'] : TRUE , FALSE ) );
$form->add( new \IPS\Helpers\Form\Translatable( 'position_description', NULL, FALSE, array(
'app' => 'applicationform',
'key' => ( $this->id ? "applicationform_position_{$this->id}_desc" : NULL ),
'editor' => array( 'app' => 'applicationform', 'key' => 'Position',
'autoSaveKey' => ( $this->id ? "applicationform-position-{$this->id}" : "applicationform-new-position" ),
'attachIds' => $this->id ? array( $this->id, NULL, 'description' ) : NULL, 'minimize' => 'position_description_placeholder' ) ) ) );$form->add( new \IPS\Helpers\Form\Translatable( 'position_instructions', NULL, FALSE, array( 'app' => 'applicationform', 'key' => ( $this->id ? "applicationform_position_{$this->id}_instructions" : NULL ), 'editor' => array( 'app' => 'applicationform', 'key' => 'Position',
'autoSaveKey' => ( $this->id ? "applicationform-position-{$this->id}-ins" : "applicationform-new-position-ins" ), 'attachIds' => $this->id ? array( $this->id, NULL, 'instructions' ) : NULL, 'minimize' => 'position_description_instructions' ) ) ) );$form->add( new \IPS\Helpers\Form\Translatable( 'position_submitmsg', NULL, FALSE, array(
'app' => 'applicationform',
'key' => ( $this->id ? "applicationform_position_{$this->id}_submitmsg" : NULL ),
'editor' => array( 'app' => 'applicationform', 'key' => 'Position',
'autoSaveKey' => ( $this->id ? "applicationform-position-{$this->id}-submitmsg" : "applicationform-new-position-submitmsg" ),
'attachIds' => $this->id ? array( $this->id, NULL, 'submitmsg' ) : NULL, 'minimize' => 'position_description_submitmsg' ) ) ) );$form->add( new \IPS\Helpers\Form\YesNo( 'position_bw_apply_only_once', $this->id ? $this->options['bw_apply_only_once'] : FALSE ) );
$formOutputTypes = [
0 => 'horizontal',
1 => 'vertical'
];$form->add( new \IPS\Helpers\Form\Radio( 'position_bw_vertical', $this->options['bw_vertical'] == 0 ? 0:1 , FALSE, ['options' => $formOutputTypes]));
$form->add( new \IPS\Helpers\Form\Url( 'position_redirect_target', $this->redirect_target , FALSE ) );$form->addTab( 'application_benefits' );
$form->add( new \IPS\Helpers\Form\Select( 'position_primary_group', $this->primary_group ?: '*', FALSE, array( 'options' => $groups, 'unlimited' => '*', 'unlimitedLang' => 'applications_do_not_change', 'unlimitedToggles' => array( 'p_return_primary' ), 'unlimitedToggleOn' => FALSE ) ) );
$form->add( new \IPS\Helpers\Form\Select( 'position_secondary_group', $this->secondary_group ?: '*', FALSE, array( 'options' => $groups, 'unlimited' => '*', 'unlimitedLang' => 'applications_do_not_change', 'unlimitedToggles' => array( 'p_return_primary' ), 'unlimitedToggleOn' => FALSE ) ) );$form->add( new YesNo( 'position_remove_promotion', $this->groupdemotion_time ? TRUE : FALSE, FALSE, ['togglesOn'=> ['position_groupdemotion_time']], NULL, NULL, NULL, 'position_remove_promotion' ) );
$form->add( new Number( 'position_groupdemotion_time', $this->groupdemotion_time, FALSE, [ ], NULL, NULL, 'days', 'position_groupdemotion_time' ) );$form->addTab( 'application_actions' );
foreach ( \IPS\Application::allExtensions( 'applicationform', 'ApplicationAction', TRUE, NULL, NULL, FALSE ) as $ext )
{$ext::form( $form, $this );
}$form->canSaveAndReload = true;
}public function formatFormValues( $values )
{foreach ( \IPS\Application::allExtensions( 'applicationform', 'ApplicationAction', TRUE, NULL, NULL, FALSE ) as $ext )
{
$ext::createFromForm( $values, $this );
}/* Bit options */
foreach ( array_keys( static::$bitOptions['options']['options'] ) as $k )
{
if ( isset( $values[ "position_{$k}" ] ) )
{
$this->options[ $k ] = $values[ "position_{$k}" ];
unset( $values[ "position_{$k}" ] );
}
}if( isset( $values['position_primary_group'] ) )
{
$values['position_primary_group'] = $values['position_primary_group'] == '*' ? 0 : $values['position_primary_group'];
}if( isset( $values['position_secondary_group'] ) )
{$values['position_secondary_group'] = $values['position_secondary_group'] == '*' ? 0 : $values['position_secondary_group'];
}if ( isset( $values['position_target_forum'] ) and \is_object( $values['position_target_forum'] ) )
{
$values['position_target_forum'] = ( $values['position_target_forum'] ) ? $values['position_target_forum']->id : 0;
}if ( $values['position_remove_promotion'] == 0)
{
$values['position_groupdemotion_time'] = 0;
}
else
{
$values['position_groupdemotion_time'] = isset( $values['position_groupdemotion_time'] ) ? $values['position_groupdemotion_time'] : 0;
}
unset( $values['position_remove_promotion'] );/* Remove position_ prefix */
$_values = $values;
$values = array();
foreach ( $_values as $k => $v )
{
if( mb_substr( $k, 0, 9 ) === 'position_' )
{
$values[ mb_substr( $k, 9 ) ] = $v;
}
else
{
$values[ $k ] = $v;
}
}if ( !$this->id )
{
$this->save();
}
\IPS\File::claimAttachments( 'applicationform-new-position', $this->id, NULL, 'description', TRUE );
\IPS\File::claimAttachments( 'applicationform-new-position-ins', $this->id, NULL, 'instructions', TRUE );
\IPS\File::claimAttachments( 'applicationform-new-position-submitmsg', $this->id, NULL, 'submitmsg', TRUE );
foreach ( array(
'name' => "applicationform_position_{$this->id}",
'description' => "applicationform_position_{$this->id}_desc",
'instructions' => "applicationform_position_{$this->id}_instructions",
'submitmsg' => "applicationform_position_{$this->id}_submitmsg",
) as $fieldKey => $langKey )
{
if ( array_key_exists( $fieldKey, $values ) )
{
\IPS\Lang::saveCustom( 'applicationform', $langKey, $values[ $fieldKey ] );if ( $fieldKey === 'name' )
{
$this->name_seo = \IPS\Http\Url\Friendly::seoTitle( $values[ $fieldKey ][ \IPS\Lang::defaultLanguage() ] );
$this->save();
}
unset( $values[ $fieldKey ] );
}
}
return $values;
}
/**
* [Node] Perform actions after saving the form
*
* @param array $values Values from the form
* @return void
*/
public function postSaveForm( $values )
{
$this->onSaveAndDelete();
}/**
* Delete Record
*
* @return void
*/
public function delete()
{
foreach ( \IPS\Application::allExtensions( 'applicationform', 'ApplicationAction', TRUE, NULL, NULL, FALSE ) as $ext )
{
$ext::onFormDelete( $this );
}\IPS\Db::i()->delete( 'applicationform_applications', ['position_id=?', $this->id ] );
\IPS\File::unclaimAttachments( 'applicationform_Position', $this->id );
try
{
\IPS\File::get( 'applicationform_Icons', $this->icon )->delete();
}
catch( \Exception $ex ) { }parent::delete();
foreach ( array(
'name' => "applicationform_position_{$this->id}",
'description' => "applicationform_position_{$this->id}_desc",
'instructions' => "applicationform_position_{$this->id}_instructions",
'submitmsg' => "applicationform_position_{$this->id}_submitmsg",
) as $fieldKey => $langKey )
{
{
\IPS\Lang::deleteCustom( 'applicationform', $langKey );
}
}/* remove menu tab */
$items = array();
foreach( \IPS\Db::i()->select( '*', 'core_menu', array( 'app=? AND extension=?', 'applicationform', 'Node' ) ) as $item )
{
$json = json_decode( $item['config'], TRUE );if ( isset( $json['applicationsforms_position_id'] ) )
{
if ( $json['applicationsforms_position_id'] == $this->id )
{
$items[] = $item['id'];
}
}
}if ( \count( $items ) )
{
\IPS\Db::i()->delete( 'core_menu', \IPS\Db::i()->in( 'id', $items ) );
unset( \IPS\Data\Store::i()->frontNavigation );
}$this->onSaveAndDelete();
}protected function onSaveAndDelete()
{
unset( \IPS\Data\Store::i()->frontNavigation );
}public function __clone()
{
if ( $this->skipCloneDuplication === TRUE )
{
return;
}$oldIcon = $this->icon;
$oldId = $this->id;
parent::__clone();foreach ( array(
'name' => "applicationform_position_{$this->id}",
'description' => "applicationform_position_{$this->id}_desc",
'instructions' => "applicationform_position_{$this->id}_instructions",
'submitmsg' => "applicationform_position_{$this->id}_submitmsg",
) as $fieldKey => $langKey )
{
{
$oldLangKey = str_replace( $this->id, $oldId, $langKey );
\IPS\Lang::saveCustom( 'applicationform', $langKey, iterator_to_array( \IPS\Db::i()->select( 'word_custom, lang_id', 'core_sys_lang_words', array( 'word_key=?', $oldLangKey ) )->setKeyField( 'lang_id' )->setValueField('word_custom') ) );
}
}if ( $oldIcon )
{
try
{
$icon = \IPS\File::get( 'applicationform_Icons', $oldIcon );
$newIcon = \IPS\File::create( 'applicationform_Icons', $icon->originalFilename, $icon->contents() );
$this->icon = (string) $newIcon;
}
catch ( \Exception $e )
{
$this->icon = NULL;
}$this->save();
}
$this->onSaveAndDelete();
}public function get_form()
{$form = new \IPS\Helpers\Form('application', 'submit' );
if ( $this->options['bw_vertical'] )
{
$form->class = 'ipsForm_vertical';
}foreach ( $this->fields AS $field )
{
$form->add( $field );
}return $form;
}public static $fieldsLookup = [];
/**
* @param $values
* @return array
*/
public function prepareValues ( $values )
{
$_values = $values;
$values = [];foreach ( $_values as $id => $data )
{
$id = explode('_', $id);
$field = \IPS\applicationform\Position\Field::load( $id[1] );
$helper = $field->buildHelper();
$helperClass = \get_class($helper);
$readableValue = $field->displayValue( $helper->stringValue($data) );switch ($helperClass )
{
case 'IPS\Helpers\Form\Member':
if( \is_int( $readableValue ) )
{
$readableValue = \IPS\Member::load( $readableValue )->name;
}
break;
case 'IPS\Helpers\Form\Date':
if ( \is_int( $readableValue ) )
{
$ts = \IPS\DateTime::ts( $readableValue) ->fullYearLocaleDate();
$readableValue = (string) $ts;
}break;
}static::$fieldsLookup[$field->_title] = $id[1];
$values[ $field->_title ] = $readableValue;
}return $values;
}public function handleForm( array $values )
{
foreach ( \IPS\Application::allExtensions( 'applicationform', 'ApplicationAction', TRUE, NULL, NULL, FALSE ) as $ext )
{
$ext::onSubmit( $this, $values );
}/* Log Data */
$id = \IPS\Db::i()->insert( 'applicationform_applications', $this->dataToLog );/* Send Notification */
if( $this->showInModcp )
{
\IPS\applicationform\Helper\Notification::sendNotificationForSubmission( $id );
}
\IPS\applicationform\Application::fireEvent( 'applicationform.application.submitted', $this );
}
public function prepareDataForSave($values )
{
$_values = $values;
$values = [];foreach ( $_values as $id => $data )
{
$id = explode('_', $id);
$field = \IPS\applicationform\Position\Field::load( $id[1] );
$helper = $field->buildHelper();
$readableValue = $helper->stringValue($data);
if ( $field->type === 'Editor' )
{
$field->claimAttachments( $id[1] );
}$values[$id[1]] = $readableValue;
}return $values;
}/**
* @return array
*/
public function get_fields()
{
$return = [];
foreach ( $this->children() as $field )
{
$return[$field->id] = $field->buildHelper( $field->value );
}return $return;
}public static function topicHasApplication( \IPS\forums\Topic $topic )
{
try
{
$pid= \IPS\Db::i()->select('position_id', 'applicationform_applications', ['topic_id=?', $topic->tid] )->first();
return static::load( $pid );
}
catch ( \UnderflowException $e )
{
return FALSE;
}
}public function getButtons($url, $subnode = FALSE)
{
if ( $this->hasChildren() )
{
$myButton['view'] = array(
'icon' => 'eye ',
'title' => 'view',
'link' => $url->setQueryString( ['do' => 'applications', 'id' => $this->_id ] ),
);
return array_merge( $myButton , parent::getButtons($url, $subnode) );
}return parent::getButtons($url, $subnode);
}public function can( $permission, $member=NULL, $considerPostBeforeRegistering = true)
{
if ( !$this->hasChildren() )
{
return FALSE;
}
return parent::can($permission, $member);
}/**
* @return bool
*
*/
public function canApply( &$errorReason = NULL )
{
if ( $this->options[ 'bw_apply_only_once'] AND $this->alreadyApplied() )
{
$errorReason ='app_already_applied';
return FALSE;
}if ( !$this->can('reply') )
{
$errorReason ='app_no_reply_perm';
return FALSE;
}return $this->can('view');
}public function modcpUrl()
{
return \IPS\Http\Url::internal( "app=core&module=modcp&controller=modcp&tab=application_approval&action=viewApplications&id={$this->id}", 'front' );
}public function get_openApplications()
{
return \IPS\Db::i()->select( 'count(*)', 'applicationform_applications', ['position_id=? AND approved=0', $this->_id ] )->first();
}public function get__badge()
{
if ( $this->hasChildren() === FALSE )
{
return array(
0 => 'ipsBadge ipsBadge_negative',
1 => 'application_not_usable',
);
}
}public function alreadyApplied()
{
try
{
$count = \IPS\Db::i()->select( 'count(*)', 'applicationform_applications', ['member_id=? AND position_id=?', \IPS\Member::loggedIn()->member_id , $this->_id ] )->first();
return !( $count < 1 );
}
catch ( \UnderflowException $e ) {
return FALSE;
}
}
public function addDataToLog( $name, $value )
{
if ( !isset($this->dataToLog[$name]) )
{
$this->dataToLog[$name] = $value;
}
}
/**
* @param \IPS\Member|null $authorizedMember
* @param null $otherFields
* @return array
*/
public function apiOutput( \IPS\Member $authorizedMember = NULL, $otherFields = NULL ) : array
{
return array(
'id' => $this->id,
'title' => $this->_title,
);
}
}
class _AlreadyAppliedException extends \LogicException
{}
Here's the default app:
-
4 minutes ago, cyr4x said:
вы же оба идеально владеете русским языком, для чего англ?
I'm not. 😂
I have to use Google Translate to communicate in Russian, and Desti knows that. He's just being considerate and making it easier for me.
-
6 minutes ago, Desti said:
I dont use recaptcha, cant check now (dont have api key for local test site).
See if this helps you (IPS default key):
SpoilerSite key: 6LcH7UEUAAAAAIGWgOoyBKAqjLmOIKzfJTOjyC7z
Secret key: 6LcH7UEUAAAAANmcQmZErdGW2FXwVhtRBVXBWBUA -
Can you share screenshots of what you have and what you'd like to have? At least a concept?
Maybe the Bug Tracker app would do the work for you, but you would have to use that instead of Nexus/Commerce support tickets. Nexus was entirely built to work in your AdminCP, so I don't think it's too easy changing it to work externally.
-
7 minutes ago, by_ix said:
BlackShot пока нет возможности проверить это.
Извини, что ты имеешь ввиду? Я могу поделиться файлом с изменениями, которые я сообщил в основном посте, если хотите. Это поможет? 😬
-
-
Если кто-нибудь знает о приложении или плагине, использующем reCaptcha, сообщите мне, чтобы я мог изучить или сравнить коды. Спасибо!
-
Привет,
Я пытаюсь добавить, чтобы добавить reCaptcha для гостей для приложения «Application Forms».
Я пошел в: sources\Position\Position.php
Я изменил его с:
Spoilerpublic function get_form()
{$form = new \IPS\Helpers\Form('application', 'submit' );
if ( $this->options['bw_vertical'] )
{
$form->class = 'ipsForm_vertical';
}foreach ( $this->fields AS $field )
{
$form->add( $field );
}return $form;
}К:
Spoilerpublic function get_form()
{$form = new \IPS\Helpers\Form('application', 'submit' );
if ( $this->options['bw_vertical'] )
{
$form->class = 'ipsForm_vertical';
}foreach ( $this->fields AS $field )
{
$form->add( $field );
}
if ( !\IPS\Member::loggedIn()->member_id )
{
$form->add( new \IPS\Helpers\Form\Captcha );
}return $form;
}reCaptcha добавляется в форму, но при нажатии «отправить» пользователь возвращается обратно, а не на страницу подтверждения отправки.
Интересно, чего мне здесь не хватает. Я сравнил с приложениями IPS, и большинство из них имеют только эту строку кода. Ничего особенного.
-
Как вы думаете, вы можете протянуть мне руку здесь?
Пытаюсь добавить reCaptcha для гостей. Я пошел в: sources\Position\Position.php
Я изменил его с:
Spoilerpublic function get_form()
{$form = new \IPS\Helpers\Form('application', 'submit' );
if ( $this->options['bw_vertical'] )
{
$form->class = 'ipsForm_vertical';
}foreach ( $this->fields AS $field )
{
$form->add( $field );
}return $form;
}К:
Spoilerpublic function get_form()
{$form = new \IPS\Helpers\Form('application', 'submit' );
if ( $this->options['bw_vertical'] )
{
$form->class = 'ipsForm_vertical';
}foreach ( $this->fields AS $field )
{
$form->add( $field );
}
if ( !\IPS\Member::loggedIn()->member_id )
{
$form->add( new \IPS\Helpers\Form\Captcha );
}return $form;
}reCaptcha добавляется в форму, но при нажатии «отправить» пользователь возвращается обратно, а не на страницу подтверждения отправки.
-
18 hours ago, Desti said:
system/CustomField/CustomField.php -
Search json_encode and edit string
$values[ static::$databasePrefix . $k ] = ( $k === 'content' ? json_encode( $_value, JSON_UNESCAPED_UNICODE ) : $_value );
All custom field (and nexus too) must work properly
Aha! Works perfectly now - you're a legend! Why do you think IPS didn't have that added in the first place? You think they just missed it, didn't consider their international userbase, or does it affect performance/security? 🤔
-
-
3 hours ago, Desti said:
$forum - big object with data, $forum->id - small part of this object, forum ID. If you need in your function all forum data, you must set $forum as arg, but if you need only ID, set $forum->id as arg.
function test($forum) { // arg as object ( called as test($forum) )
return $forum->id. '---> ' . $forum->name; // you use data from object
}and
function test($forum) { // arg as ID only ( called as test($forum->id) )
return 'Forum ID: $forum; // you use id only}
Depends on the complexity of the task that the function solves. Simple true-false checks can be placed in the template, complex calculations and database queries can be placed in the hook function.
And in this case, such data (id, name) can be found in forums\sources\Forum\Forum.php, right? Which is where the class \IPS\forums\Forum is located in.
This is becoming fun - I feel like I've been learning a lot from you and these forums. Do you recommend any guides, videos or content for beginners at coding, Desti? Or do you have any tips? I'm finding all of this super interesting. I hope to contribute a lot more in the future with plugins and (who knows?) apps.
-
1 hour ago, Desti said:
1. Publiс function. No "public static" -> public function forumstyles( $forum ) { ... }
2. no type declaration on function variable
3. in template you must add param to function -> {{if $forum->forumstyle( $forum->name )}} - for example.if ( \IPS\Settings::i()->forumstyle == 'style2' AND in_array( $forum, explode(',', \IPS\Settings::i()->fs_forums)) ) - this you can insert directly into the template, no hook needed
{{if \IPS\Settings::i()->forumstyle == 'style2' AND in_array( $forum->id(or what?), explode(',', \IPS\Settings::i()->fs_forums)) }} - i don't know what is stored in\IPS\Settings::i()->fs_forums...\IPS\Settings::i()->fs_forums - array of ID, you must use $forum->id
Wow, I can't believe a function wasn't necessary at all. What would be the purpose of having a function then? To make it easier and simpler if you have a lot of theme hooks, for example?
Everything works fine now, thanks to you Desti! I even removed the 'forumstyle' setting. Just a list of forums is enough for now.
BTW, where can I check if an argument like $forum is enough or if I need to write $forum->id?
-
21 minutes ago, Desti said:
$forum in template is instance of \IPS\forums\Forum. U can see it if var_dump $forum variable
And your hook must be from \IPS\forums\Forum
Great tip!! I didn't know about var_dump, it'll make it much easier from now on. I was able to reproduce it here:
SpoilerSo, now that we have figured the hook has to be from \IPS\forums\Forum, what would be the proper function? static function? Just function? Do I add \IPS\forums\Forum before $forum? This is the most confusing part for me. I'm trying this but it's still throwing an error:
Spoiler//<?php
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
exit;
}class hook113 extends _HOOK_CLASS_
{
public static function forumstyles( $forum )
{
try
{
if ( \IPS\Settings::i()->forumstyle == 'style2' AND in_array( $forum, explode(',', \IPS\Settings::i()->fs_forums)) )
{
return TRUE;
}return FALSE;
}
catch ( \RuntimeException $e )
{
if ( method_exists( get_parent_class(), __FUNCTION__ ) )
{
return \call_user_func_array( 'parent::' . __FUNCTION__, \func_get_args() );
}
else
{
throw $e;
}
}
}
} -
4 minutes ago, Desti said:
You call instance of \IPS\forums\Forum ($forum), but add function to \IPS\forums\modules\front\forums\index, why?
I'm not sure I learned the logic of classes and functions yet, so I just checked other plugins and tried to do something similar. What do you suggest I do instead, or how should I think like so the functions make sense?
Edit:
From my newbie perspective, I think adding it to '\IPS\forums\modules\front\forums\index' makes sense because that's where forumRow is located in. I also think it makes sense adding it to \IPS\forums\modules\front\forums\forums, because that's where I see the argument $forum being created.
-
I've also tried different types of functions and arguments, like:
Spoilerpublic function forumstyles( $forum )
public function forumstyles( \IPS\forums\Forum $forum )
public static function forumstyles( \IPS\forums\Forum $forum )
etc. -
8 hours ago, Desti said:
Firstly.. when u "replace" something in theme hook, you don't replace the line you selected, but everything that includes this tag.
if html like
<div class='black'>
<ul>...
<li>....
</div>and you select first string, your hook replace all div, not first (<div class='black'>) string
You're right. I was making the plugin so late at night that I didn't realize such silly mistakes. There were others too, like having an extra '(' somewhere or not using the proper setting name.
It's a bit better, but I'm getting this message now:
Spoiler[[Template forums/front/index/forumRow is throwing an error. This theme may be out of date. Run the support tool in the AdminCP to restore the default theme.]]
1st hook (theme): \IPS\Theme\class_forums_front_index
Spoiler{{if $forum->forumstyle()}}
<ul class="ipsDataItem_subList ipsList_csv">
{{else}}
<ul class="ipsDataItem_subList ipsList_inline">
{{endif}}
{{foreach $forum->children() as $subforum}}
<li class="{{if \IPS\forums\Topic::containerUnread( $subforum )}}ipsDataItem_unread{{endif}}">
<a href="{$subforum->url()}">{{if \IPS\forums\Topic::containerUnread( $subforum )}}<span class='ipsItemStatus ipsItemStatus_tiny {{if !\IPS\forums\Topic::containerUnread( $subforum ) && !$subforum->redirect_on}}ipsItemStatus_read{{endif}}'><i class="fa fa-circle"></i></span> {{endif}}{$subforum->_title}</a>
</li>
{{endforeach}}
</ul>2nd hook (code): \IPS\forums\modules\front\forums\forums
Spoiler//<?php
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
exit;
}class hook109 extends _HOOK_CLASS_
{
public function forumstyles( $forum )
{
try
{
if ( \IPS\Settings::i()->forumstyle == 'style1' AND in_array( $forum, explode(',', \IPS\Settings::i()->fs_forums)) )
{
return TRUE;
}return FALSE;
}
catch ( \RuntimeException $e )
{
if ( method_exists( get_parent_class(), __FUNCTION__ ) )
{
return \call_user_func_array( 'parent::' . __FUNCTION__, \func_get_args() );
}
else
{
throw $e;
}
}
}
}Settings:
{{if $forum->forumstyle()}} is actually {{if $forum->forumstyles()}}, but I'm still getting an error.
-
Привет ребят,
Я получаю следующую ошибку для очень простого плагина. Поскольку я не силен в программировании, я пытаюсь сделать свой собственный плагин, сравнивая его с другими. Поэтому я не уверен, что я делаю неправильно, но я потратил много часов, пытаясь это исправить. Неудачно.
SpoilerUnexpectedValueException: (0)
#0 domain.com/applications/forums/modules/front/forums/index.php(216): IPS\_Theme->getTemplate('index')
#1 domain.com/system/Dispatcher/Controller.php(101): IPS\forums\modules\front\forums\_index->manage()
#2 domain.com/applications/forums/modules/front/forums/index.php(52): IPS\Dispatcher\_Controller->execute()
#3 domain.com/system/Dispatcher/Dispatcher.php(153): IPS\forums\modules\front\forums\_index->execute()
#4 domain.com/index.php(13): IPS\_Dispatcher->run()
#5 {main}1st hook (theme): \IPS\Theme\class_forums_front_index
CSS selector: li.cForumRow.ipsDataItem.ipsDataItem_responsivePhoto.ipsClearfix > div.ipsDataItem_main > ul.ipsDataItem_subList.ipsList_inlineSpoiler{{if $forum->forumstyle() )}}
<ul class="ipsDataItem_subList ipsList_inline">
{{else}}
<ul class="ipsDataItem_subList ipsList_csv">
{{endif}}2nd hook (code): \IPS\forums\modules\front\forums\forums
Spoiler//<?php
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
exit;
}class hook94 extends _HOOK_CLASS_
{
public static function forumstyles( \IPS\forums\Forum $forum )
{
try
{
if ( \IPS\Settings::i()->fs_style1 == 'style1' AND in_array( $forum, explode(',', \IPS\Settings::i()->fs_forums)) )
{
return TRUE;
}return FALSE;
}
catch ( \RuntimeException $e )
{
if ( method_exists( get_parent_class(), __FUNCTION__ ) )
{
return \call_user_func_array( 'parent::' . __FUNCTION__, \func_get_args() );
}
else
{
throw $e;
}
}
}
}Я также пытался расширить \IPS\forums\modules\front\forums\index, но это тоже не работает. Я даже пытался изменить функции кода, та же ошибка.
Может ли кто-нибудь указать мне правильное направление?
-
2 hours ago, Desti said:
Пробовали ли вы создать пользовательское *текстовое* поле в Nexus/Commerce? Я получил этот ответ от кого-то:
QuoteПрежде всего, \u00e3 не генерируется MySQL. Однако он может быть сгенерирован функцией PHP json_encode(). Обязательно используйте JSON_UNESCAPED_UNICODE во втором аргументе этой функции.
Для использования в таблицах MySQL я предпочитаю, чтобы настройки подключения и сервера были постоянно установлены на utf8mb4, чтобы данные Unicode просто появлялись и исчезали без преобразования.
-
5 hours ago, AnWey said:
Я CloudFlare переводил в режим разработчика, чтоб отключить кеширование, увы не помогло.
Это не должно помочь. Похоже, это не связано с настройками CloudFlare. Ваш сервер падает, когда вы устанавливаете IPS, даже если на несколько секунд. Держу пари, это связано с ресурсом вашего сервера. Вы можете сначала попробовать установить IPS на свой локальный компьютер. Если это работает, вы точно знаете, что это ваш хост. Вы также можете связаться с ними по поводу времени безотказной работы онлайн и производительности.
Установка настраиваемого поля в качестве обязательного поля
в Техническая поддержка Invision Community
Опубликовано
I've added it to the proper file and unset its value - it works! The only downside to this is it adds a checkbox for every form created, whereas I only wanted it to show for specific ones. But that's still better than changing so much code, right? Thanks, Desti 🏆