datamweb / codeigniter-multi-captcha

Multi captcha package for CodeIgniter 4.x. Support Arcaptcha(a free and professional Iranian product),Bibot(a free Iranian product),Recaptcha(an googel product) and hCaptcha.Comes with rate limiting support.
MIT License
19 stars 3 forks source link

Install issues #1

Closed MarcPinnell closed 1 year ago

MarcPinnell commented 1 year ago

Love the promise of this library, but having issues getting it to run. Followed the instructions you set, but when I try to pull up the contact form I get:

Call to undefined function CIMC_JS()

I looked at the short video you have online and noticed the command: setup:cimc --show

But when I run that, I get: Command "setup:cimc" not found.

In the video, there is a reference to a line in "generator" but there is nothing in the instructions for that.

Help!

datamweb commented 1 year ago

Hi @MarcPinnell , nice to have you here. Regarding command setup:cimc, I was going to post it, but I left it because I didn't get any feedback.

Regarding receiving error, you need to load helper ci_multi_captcha.

helper(['ci_multi_captcha','form','url']);

To be honest, if I were to write this library today, I would consider many changes in its design. This was my first experience, I like it very much.

MarcPinnell commented 1 year ago

I removed all the stuff in the third party folder and then tried the composer install. No change. Where do I set all the paths and keys using the composer install?

MarcPinnell commented 1 year ago

I removed the composer install and went back to the manual for now. Added the helper and it is now working.

Did you just update something. I would swear the install instructions changed in the last hour.

MarcPinnell commented 1 year ago

Sorry, one last question (I hope). I put the code you show on the contact form and it works great. But you also say I need to put something in a controller: "CIMC_FIELD('hcaptcha) => CIMC_RULE(),"

What controller? The contact form processor?

datamweb commented 1 year ago

something in a controller: "CIMC_FIELD('hcaptcha) => CIMC_RULE(),"

see here :

https://github.com/datamweb/codeIgniter-multi-captcha/blob/316b47f7e2c636e4adbd0f3dd555ae48e4b840f5/CIMultiCaptcha/Controllers/RateLimit.php#L79

MarcPinnell commented 1 year ago

It's already there... Seems to be working without me doing anything.

datamweb commented 1 year ago

No, it is not, you must define in the rules that you have a captcha, otherwise, if the captcha is not solved, it is possible to jump to the next step without checking the captcha answer.

MarcPinnell commented 1 year ago

Ok, you are correct. While it is showing the hcaptcha, it isn't actually stopping me from submitting form. So, I am confused on what step is missing from instructions.

In my contact form view file I have:

<?php echo CIMC_JS('hcaptcha'); echo CIMC_ERROR(); echo CIMC_HTML(['captcha_name'=>'hcaptcha']); ?>

I am still not clear on where I am supposed to add the line: CIMC_FIELD('hcaptcha) => CIMC_RULE(),

And the ratelimit.php file has (in part): if($this->request->getPost('submit')) { $rules=[CIMC_FIELD($this->CaptchaName) =>CIMC_RULE()]; if (! $this->validate($rules))

datamweb commented 1 year ago

Send the minimum controller code.

MarcPinnell commented 1 year ago

For the contact form?

public function contact_us_send()
{
    $post = $this->request->getPost();
    $email = service('email');
    //Get admin emails
    $users = model(UserModel::class);
    $adminEmails = $users->getAdminEmails();

    $email->setSubject('New Contact Form Submission');

    $emailBody = '<p><strong>Name:</strong> '.$post['name_main'].'</p>';
    $emailBody .= '<p><strong>Business Name:</strong> '.$post['name_biz'].'</p>';
    $emailBody .= '<p><strong>Address:</strong> '.$post['address_street'].'; '.$post['address_city'].', '.$post['address_state'].'  '.$post['address_zip'].'</p>';
    $emailBody .= '<p><strong>Phone:</strong> '.$post['phone_main'].'</p>';
    $emailBody .= '<p><strong>Email:</strong> '.$post['email'].'</p>';
    $emailBody .= '<p><strong>Email Updates?</strong> '.($post['updates'] ? 'Yes':'No').'</p>';
    $emailBody .= '<p><strong>Comments:</strong><br/>'.$post['comments'].'</p>';
    $email->setMessage($emailBody);

    //Send it!
    if (!$email->send()) {
        dd($email->printDebugger());
    }

    return view('Public/contact_us_thank_you');
}
datamweb commented 1 year ago

It doesn't help. I'll record a video tomorrow.

MarcPinnell commented 1 year ago

Thanks for all your help so far!

datamweb commented 1 year ago

I will create a simple form with the controller, so you can understand, do you need anything else?

MarcPinnell commented 1 year ago

Nope I think that is the last piece. It is working fine except that you can skip the verification.

I am still using the composer install. Composer didn't remove it earlier when I thought I did. It started working when I redid the setup. Because of that I put the hcaptcha keys in the config file per instructions, but seems odd that I should be modifying the file that is inside vendor directory. If you are going to do another version, might want to move the keys to the .env file so they don't get overwritten when doing updates via composer.

datamweb commented 1 year ago

If you are going to do another version, might want to move the keys to the .env file so they don't get overwritten when doing updates via composer.

Added two features:

  1. Command cimc:publish To use it, run the following command.

    php spark cimc:publish

    Then go to app/Config/MultiCaptchaCIConfig.php and set the keys (or any other properties).

  2. The use of env was added, just add the keys to the .env file as below for each captcha.(The priority is if set with file env)

    multiCaptcha.arCaptcha.siteKey = 82ab22rpn4
    multiCaptcha.arCaptcha.secretKey = ld469lmgqq9ht2u6f7q4
    multiCaptcha.hCaptcha.siteKey = 82ab22rpn4
    multiCaptcha.hCaptcha.secretKey = ld469lmgqq9ht2u6f7q4
    # and ...
MarcPinnell commented 1 year ago

Nice work and fast! Can you explain what the publish command does?

datamweb commented 1 year ago

It just create a copy of file vendor\datamweb\codeIgniter-multi-captcha\CIMultiCaptcha\Config\MultiCaptchaCIConfig.php with slightly changed contents in path app\Config\MultiCaptchaCIConfig.php .

This will make you not need to set in file vendor\datamweb\codeIgniter-multi-captcha\CIMultiCaptcha\Config\MultiCaptchaCIConfig.php.

In case of updating, there is no problem because the settings are made in file app\Config\MultiCaptchaCIConfig.php, not vendor\datamweb\codeIgniter-multi-captcha\CIMultiCaptcha\Config\MultiCaptchaCIConfig.php.

MarcPinnell commented 1 year ago

Nice! I like that.

Were you able to put together the sample contact form?

datamweb commented 1 year ago

Yes, the only problem we have is that the government here has recently created many problems to use the Internet, in fact the file upload speed is so slow that it actually takes me several hours/day to upload. Can the sample code be enough for you?

Screenshot 2023-03-29 193849

MarcPinnell commented 1 year ago

I have the captcha working on the contact form, but you can just ignore it and hit submit without it failing. Seems like I need something in my controller file (posted above). Just not sure what.

Screenshot 2023-03-29 at 8 14 01 AM

datamweb commented 1 year ago

but you can just ignore it and hit submit without it failing. Seems like I need something in my controller file (posted above). Just not sure what.

You must define rules for each field, and then check in the controller whether the rules are set.

Controller:

<?php

namespace App\Controllers;

class Home extends BaseController
{
    public function index()
    {
        helper(['ci_multi_captcha', 'form', 'url']);

        if (!$this->request->is('post')) {
            return view('welcome_message');
        }

        $rules =[
            'fname' => [
                'label' => 'Test.fname',
                'rules' => 'required|in_list[pooya,ali]',
            ],
            CIMC_FIELD('arcaptcha') => CIMC_RULE(),

        ];

        if (!$this->validate($rules)) {
            return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
        }

        return redirect()->back()->withInput()->with('message', 'all field is OK!');

    }
}

view :

    <!-- CONTENT -->

    <section>

        <?php if (session('error') !== null) : ?>
            <div class="alert alert-danger" role="alert"><?= session('error') ?></div>
        <?php elseif (session('errors') !== null) : ?>
            <div class="alert alert-danger" role="alert">
                <?php if (is_array(session('errors'))) : ?>
                    <?php foreach (session('errors') as $error) : ?>
                        <?= $error ?>
                        <br>
                    <?php endforeach ?>
                <?php else : ?>
                    <?= session('errors') ?>
                <?php endif ?>
            </div>
        <?php endif ?>

        <?php if (session('message') !== null) : ?>
            <div class="alert alert-success" role="alert"><?= session('message') ?></div>
        <?php endif ?>

        <form action="<?= url_to('/') ?>" method="post">
            <?= csrf_field() ?>

            <!-- fname -->
            <div class="mb-2">
                <input type="text" class="form-control" name="fname" inputmode="text" placeholder="<?= lang('Test.fname') ?>" required />
            </div>
            <?= CIMC_HTML(['captcha_name' => 'arcaptcha']); ?>

            <div class="d-grid col-12 col-md-8 mx-auto m-3">
                <button type="submit" class="btn btn-primary btn-block"><?= lang('Test.form') ?></button>
            </div>

        </form>
        <?php echo CIMC_JS('arcaptcha'); ?>

    </section>

Route:

$routes->get('/', 'Home::index');
$routes->post('/', 'Home::index');
MarcPinnell commented 1 year ago

Ah! Now I understand. Thank you for your patience! I will work on getting the captcha code updated today and then work on finishing integration.

MarcPinnell commented 1 year ago

Doesn't look like you advanced the version number, can I just update the files I see that have been touched manually in the vendor folder or is there a better way?

datamweb commented 1 year ago

In CI4-project-root/composer.json add "datamweb/codeigniter-multi-captcha":"dev-main"

  "require": {
        "php": "^7.4 || ^8.0",
        "codeigniter4/framework": "^4.0",
        "datamweb/codeigniter-multi-captcha":"dev-main"
    },

Run :

composer update

OR Download and instal manually

MarcPinnell commented 1 year ago

If you are going to do another version, might want to move the keys to the .env file so they don't get overwritten when doing updates via composer.

Added two features:

  1. Command cimc:publish To use it, run the following command.

    php spark cimc:publish

    Then go to app/Config/MultiCaptchaCIConfig.php and set the keys (or any other properties).

[CodeIgniter\Files\Exceptions\FileException]

__construct expects a valid directory.

at SYSTEMPATH/Files/FileCollection.php:52

Backtrace: 1 SYSTEMPATH/Files/FileCollection.php:52 CodeIgniter\Files\Exceptions\FileException::forExpectedDirectory()

2 SYSTEMPATH/Publisher/Publisher.php:159 CodeIgniter\Files\FileCollection::resolveDirectory()

3 VENDORPATH/datamweb/codeigniter-multi-captcha/CIMultiCaptcha/Commands/CIMCaptchaPublish.php:35 CodeIgniter\Publisher\Publisher()->__construct()

4 SYSTEMPATH/CLI/Commands.php:65 Datamweb\CIMC\Commands\CIMCaptchaPublish()->run()

5 SYSTEMPATH/CLI/Console.php:37 CodeIgniter\CLI\Commands()->run()

6 ROOTPATH/spark:97 CodeIgniter\CLI\Console()->run()

datamweb commented 1 year ago

I have made some changes, can you install a clean version of the codeigniter framework and then install codeigniter-multi-captcha with the command below?

composer require datamweb/codeigniter-multi-captcha:dev-main
MarcPinnell commented 1 year ago

Not sure what you mean about a clean version of framework? This is a large app, I can't delete it.

I did try deleting the datamweb directory from vendor then running composer require like you said and it restored the directory, but I am still getting the same error when I try to the publish command.

With that said I looked at the code in the publish command and manually applied the replacements to a copy of the config file (after moving it) and it seems to be working.

MarcPinnell commented 1 year ago

Now when I submit the contact form I am getting: ""hcaptcha" is not a valid rule." with this code:

        $post = $this->request->getPost();

        $rules =[
            CIMC_FIELD('hcaptcha') => CIMC_RULE(),
        ];

        if (!$this->validate($rules)) {
            return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
        }

        return redirect()->back()->withInput()->with('message', 'all field is OK!');

The required helpers are in the basecontroller

datamweb commented 1 year ago

Now when I submit the contact form I am getting: ""hcaptcha" is not a valid rule." with this code:

Go to the app/Config path and add the following values in the Validation.php file.

 public $ruleSets = [
        // Add this line
        '\Datamweb\CIMC\Validation\RulesCIMC',
    ];
    public $templates = [
        // Add this line
        'CIMC_ERRORS_LIST'      => 'Datamweb\CIMC\Validation\Views\_list.php',
        // Add this line
        'CIMC_ERRORS_SINGLE'    => 'Datamweb\CIMC\Validation\Views\_single.php',
    ];

Have you added fileapp\Config\Autoload.php like below?

    public $psr4 = [
        APP_NAMESPACE => APPPATH, // For custom app namespace
        'Config'      => APPPATH . 'Config',
        'Datamweb\CIMC'             => APPPATH . 'ThirdParty\CIMultiCaptcha',
    ];

And what is your CI framework version?

MarcPinnell commented 1 year ago

The $ruleSets was missing. Must have missed it when I was initially installing and had to redo it twice when I tried to switch to composer from manual.

Adding the ruleset fixed it.

I am running CI 4.3.3

datamweb commented 1 year ago

The error you are getting is probably due to the presence of 'Datamweb\CIMC' => APPPATH . 'ThirdParty\CIMultiCaptcha', in file app\Config\Autoload.php. delete it

    public $psr4 = [
        APP_NAMESPACE => APPPATH, // For custom app namespace
        'Config'      => APPPATH . 'Config',
    ];

Then run command php spark cimc:publish, no error should be displayed.

MarcPinnell commented 1 year ago

Yep that did it!

Thanks for your patience working through this.

datamweb commented 1 year ago

Also the documentation is not good and I need to improve the documentation.

Currently, due to the existence of the demo file, the size of the package is very high, I will soon remove the demo file from the source.

Thanks!