Posted 21 февраля, 20222 yr comment_178186 Привет, Я пытаюсь добавить, чтобы добавить reCaptcha для гостей для приложения «Application Forms». Я пошел в: sources\Position\Position.php Я изменил его с: Spoiler 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; } К: Spoiler 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 ); } if ( !\IPS\Member::loggedIn()->member_id ) { $form->add( new \IPS\Helpers\Form\Captcha ); } return $form; } reCaptcha добавляется в форму, но при нажатии «отправить» пользователь возвращается обратно, а не на страницу подтверждения отправки. Интересно, чего мне здесь не хватает. Я сравнил с приложениями IPS, и большинство из них имеют только эту строку кода. Ничего особенного.
22 февраля, 20222 yr Author comment_178196 Если кто-нибудь знает о приложении или плагине, использующем reCaptcha, сообщите мне, чтобы я мог изучить или сравнить коды. Спасибо!
22 февраля, 20222 yr Author comment_178231 7 minutes ago, by_ix said: BlackShot пока нет возможности проверить это. Извини, что ты имеешь ввиду? Я могу поделиться файлом с изменениями, которые я сообщил в основном посте, если хотите. Это поможет? 😬
22 февраля, 20222 yr comment_178234 I dont use recaptcha, cant check now (dont have api key for local test site).
22 февраля, 20222 yr Author comment_178235 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): Spoiler Site key: 6LcH7UEUAAAAAIGWgOoyBKAqjLmOIKzfJTOjyC7zSecret key: 6LcH7UEUAAAAANmcQmZErdGW2FXwVhtRBVXBWBUA
22 февраля, 20222 yr comment_178236 38 минут назад, Desti сказал: I dont use recaptcha, cant check now (dont have api key for local test site). вы же оба идеально владеете русским языком, для чего англ?
22 февраля, 20222 yr Author comment_178237 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. Edited 22 февраля, 20222 yr by BlackShot
22 февраля, 20222 yr comment_178239 4 минуты назад, BlackShot сказал: I have to use a translator to communicate in Russian Wow, I didn't even know that, sorry
22 февраля, 20222 yr comment_178242 $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=...)
22 февраля, 20222 yr Author comment_178243 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: Application Forms 3.5.0 (2).tar Edited 22 февраля, 20222 yr by BlackShot
22 февраля, 20222 yr comment_178245 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);
22 февраля, 20222 yr Author comment_178248 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. 😂
22 февраля, 20222 yr comment_178250 O problema é que esta aplicação processa os dados recebidos do formulário estritamente de acordo com o algoritmo. E se um campo extra aparece na lista de campos de formulário, todo o algoritmo entra em colapso. Depois de remover o campo extra antes de processar, retornamos tudo ao estado padrão. Если в полях формы обнаруживается лишнее поле, вся стройная система падает, даже без диагностики. Поэтому удаляем капчевое поле перед обработкой.
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.