News:

SMF 2.1.4 has been released! Take it for a spin! Read more.

Main Menu

Posting via cUrl for mod

Started by digital-pig, March 17, 2018, 09:06:30 PM

Previous topic - Next topic

digital-pig

Hey all,

I'm looking at creating a mod that will have a cron which runs and posts replies to topics based on data from GitHub. I'm having some issues getting started though as I cannot seem to create a post. I would really rather not go the route of writing directly to the database as that will not run other code/mods which check posts as they're made on the site by users.

I've included some test code here so you can see what I'm attempting. The site is locally hosted for dev.


// File: config.php

$forumUrl = 'https://forum.test';
$forumUser = 'admin';
$forumUserPassword = 'xxxxxxxx';

$testBoardId = 12;
$testTopicId = 13;




// File: cron_poster.php

require 'Application/config/config.php';
require 'Application/Tmod/ForumPoster.php';

$testLoginOnly = false;
$testVerboseOutput = false;

$test = new \Application\Tmod\ForumPoster($forumUrl, $forumUser, $forumUserPassword);
$test->test($testLoginOnly, $testVerboseOutput, $testTopicId);

print "\nDone!\n";




// File: ForumPoster.php

namespace Application\Tmod;

class ForumPoster {

    private $curlSession = null;
    private $forumUser = '';
    private $forumPass = '';
    private $forumUrl = '';

    public function __construct($url, $username, $password) {
        $this->forumUrl = $url;
        $this->forumUser = $username;
        $this->forumPass = $password;
    }

    public function test($loginOnly, $testVerboseOutput, $topicId) {
        $testResult = $this->getCurlSession($testVerboseOutput);
        if ($loginOnly) {
            curl_close($this->curlSession);
            print_r($testResult);
            exit;
        }

        if ($testResult['success'] === true) {
            $subject = 'This is a test at ' . strftime('%d-%m-%y %H:%M:%s');
            $message = 'Trying to post a test to the forum';
            $testPostResult = $this->postIssue($message, $subject, $topicId);

            if (stripos($testPostResult['debug'], $subject) !== false) {
                print "Success!";
            } else {
                print "Failed!";
            }
        } else {
            print 'Failed to get login session';
        }
        curl_close($this->curlSession);
    }

    private function postIssue($message, $subject, $topicId) {
        $ch = $this->curlSession;
        $data = '?' . http_build_query([
            'message' => $message,
            'subject' => $subject,
            'topic' => $topicId,
            'post' => 'Post',
            'notify' => 0,
            'action' => 'post2',
            'board' => 1
        ]);

        curl_setopt($this->curlSession, CURLOPT_POSTFIELDS, $data);
        $result = curl_exec($ch);
        $error = curl_error($ch);

        $success = (empty($error));
       
        return [
            'success' => $success,
            'error' => $error,
            'debug' => $result
        ];
    }

    private function getCurlSession($verboseOutput) {
        $data = '?' . http_build_query([
            'action' => 'login2',
            'user' => $this->forumUser,
            'passwrd' => $this->forumPass,
            'cookielength' => -1,
            'submit' => 'Login'
        ]);

        $curlUserAgent = 'Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11';
        $curlHttpHeader = [
            'Accept: text/plain,text/html;',
            'Accept-Language: en-us,en;q=0.5',
            'Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7',
            'Content-Length: ' . strlen($data)
        ];

        $ch = curl_init();

        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        curl_setopt($ch, CURLOPT_HEADER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $curlHttpHeader);
        curl_setopt($ch, CURLOPT_VERBOSE, $verboseOutput);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
        curl_setopt($ch, CURLOPT_TIMEOUT, 10);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_FAILONERROR, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_USERAGENT, $curlUserAgent);
        curl_setopt($ch, CURLOPT_COOKIEJAR, './cookie_jar');
        curl_setopt($ch, CURLOPT_COOKIEFILE, './cookie_jar');
        curl_setopt($ch, CURLOPT_COOKIESESSION, true);
        curl_setopt($ch, CURLOPT_URL, $this->forumUrl . '/index.php');

        $result = curl_exec($ch);
        $error = curl_error($ch);

        $success = (empty($error));
        if ($success) {
            $this->curlSession = $ch;
        } else {
            curl_close($ch);
        }
        $ch = null;

        return [
            'success' => $success,
            'error' => $error,
            'debug' => $result
        ];
    }
}



Hopefully it's easy to follow, just a curl session to get a cookie, store it, then use the session to create a post.

Any help is really appreciated.
Paul

Advertisement: