Chevereto

Chevereto Plugin

April 03, 2020 - ModerateContent Support


Our FREE Chevereto plugin provides content moderation for your image community. The plugin automatically determines via our API if the image contains adult (NSFW) content and either blocks it or forces the database to always have it flagged as NSFW.

How to install

Yes it's lengthy but it's the best process we've found until the Chevereto developers make our plugin official.

Step 1) Modify file app/lib/classes/class.upload.php so that it looks like this around line 412

        // Size
        if (!$this->options['max_size']) {
            $this->options['max_size'] = self::getDefaultOptions()['max_size'];
        }
        if ($this->source_image_fileinfo["size"] > $this->options["max_size"]) {
            throw new UploadException("File too big - max " . G\format_bytes($this->options["max_size"]), 313);
        }

        // BMP?
        if ($this->source_image_fileinfo['extension'] == 'bmp') {
            $this->ImageConvert = new ImageConvert($this->downstream, "png", $this->downstream);
            $this->downstream = $this->ImageConvert->out;
            $this->source_image_fileinfo = G\get_image_fileinfo($this->downstream);
        }

        // MODERATECONTENT PLUGIN
        // MODERATECONTENT PLUGIN
        // MODERATECONTENT PLUGIN
        if (intval(Settings::get('moderatecontent')) != 0 && intval(Settings::get('moderatecontent_action_block_upload')) != 0){
          require_once CHV_APP_PATH_LIB_VENDOR . 'moderatecontent/moderatecontent.php';
          $response = ModerateContent::moderate_image($this->downstream);
          if ($response->error_code == 0 && $response->moderation->rating_letter == "a"){
            throw new UploadException("This image contains adult content", 1404);
          }
          if ($response->error_code == 0 && $response->moderation->rating_letter == "t" && intval(Settings::get('moderatecontent_include_teen')) != 0){
            throw new UploadException("This image contains adult content", 1404);
          }
        }
        // MODERATECONTENT PLUGIN
        // MODERATECONTENT PLUGIN
        // MODERATECONTENT PLUGIN
    }

    // Handle flood uploads
    protected static function handleFlood()
    {
        $logged_user = Login::getUser();

Step 2) Modify file app/lib/classes/class.image.php so that it looks like this around line 1030

public static function insert($image_upload, $values=[])
    {
        try {
            $table_chv_image = self::$table_chv_image;
            foreach ($table_chv_image as $k => $v) {
                $table_chv_image[$k] = 'image_' . $v;
            }

            // Remove eternal/useless Exif MakerNote
            if ($image_upload['source']['image_exif']['MakerNote']) {
                unset($image_upload['source']['image_exif']['MakerNote']);
            }

            $original_exifdata = $image_upload['source']['image_exif'] ? json_encode(G\array_utf8encode($image_upload['source']['image_exif'])) : null;

            // Fix some values
            $values['nsfw'] = in_array(strval($values['nsfw']), ['0','1']) ? $values['nsfw'] : 0;

            // MODERATECONTENT PLUGIN
            // MODERATECONTENT PLUGIN
            // MODERATECONTENT PLUGIN
            if (intval(Settings::get('moderatecontent')) != 0 && intval($values['nsfw']) != 1 && intval(Settings::get('moderatecontent_action_flag_nsfw')) != 0){
              require_once CHV_APP_PATH_LIB_VENDOR . 'moderatecontent/moderatecontent.php';
              $response = ModerateContent::moderate_image($image_upload['uploaded']['file']);
              if ($response->error_code == 0){
                if ($response->moderation->rating_letter == "a"){
                  $values['nsfw'] = '1';
                }
                if ($response->moderation->rating_letter == "t" && intval(Settings::get('moderatecontent_include_teen')) != 0){
                  $values['nsfw'] = 1;
                }
              }
            }
            // MODERATECONTENT PLUGIN
            // MODERATECONTENT PLUGIN
            // MODERATECONTENT PLUGIN

Step 3) Modify file app/lib/classes/class.image.php so that it looks like this around line 1112

public static function update($id, $values)
    {
        try {
            $values = G\array_filter_array($values, self::$table_chv_image, 'exclusion');

            foreach (['title', 'description', 'category_id', 'album_id'] as $v) {
                if (!array_key_exists($v, $values)) {
                    continue;
                }
                G\nullify_string($values[$v]);
            }
            // MODERATECONTENT PLUGIN
            // MODERATECONTENT PLUGIN
            // MODERATECONTENT PLUGIN
            if (intval(Settings::get('moderatecontent')) != 0 && intval($values['nsfw']) != 1 && intval(Settings::get('moderatecontent_action_flag_nsfw')) != 0){
              require_once CHV_APP_PATH_LIB_VENDOR . 'moderatecontent/moderatecontent.php';
              $image_db = self::getSingle($id, false, false);
              $image_path = $image_db['file_resource']['chain']['image'];
              $response = ModerateContent::moderate_image($image_path);
              if ($response->error_code == 0){
                if ($response->moderation->rating_letter == "a"){
                  $values['nsfw'] = 1;
                }
                if ($response->moderation->rating_letter == "t" && intval(Settings::get('moderatecontent_include_teen')) != 0){
                  $values['nsfw'] = 1;
                }
              }
            }
            // MODERATECONTENT PLUGIN
            // MODERATECONTENT PLUGIN
            // MODERATECONTENT PLUGIN

Step 4) Modify file app/themes/Peafowl/views/dashboard.php so that it looks like this around line 2172. If your not using the theme Peafowl then you will have to find the right spot to insert this code into your themes dashboard.php file.

<hr class="line-separator"></hr>
			<div class="input-label">
				<label for="cloudflare">Cloudflare</label>
				<div class="c5 phablet-c1"><select type="text" name="cloudflare" id="cloudflare" class="text-input"  >
					<?php
                        echo CHV\Render\get_select_options_html([1 => _s('Enabled'), 0 => _s('Disabled')], CHV\Settings::get('cloudflare')); ?>
				</select></div>
				<div class="input-below"><?php echo read_the_docs(['%s' => 'CloudFlare', '%k' => 'cloudflare']); ?></div>
			</div>

      <!-- MODERATECONTENT PLUGIN -->
      <!-- MODERATECONTENT PLUGIN -->
      <!-- MODERATECONTENT PLUGIN -->
			<hr class="line-separator"></hr>
			<div class="input-label">
				<label for="moderatecontent">ModerateContent</label>
				<div class="c5 phablet-c1"><select type="text" name="moderatecontent" id="moderatecontent" class="text-input" data-combo="moderatecontent-combo">
					<?php
                        echo CHV\Render\get_select_options_html([1 => _s('Enabled'), 0 => _s('Disabled')], CHV\Settings::get('moderatecontent')); ?>
				</select></div>
				<div class="input-below"><?php echo read_the_docs(['%s' => 'ModerateContent', '%k' => 'moderatecontent']); ?></div>
			</div>
      <div id="moderatecontent-combo" class="c12 phablet-c1">
					<div class="input-label">
						
            <div data-combo-value="1" class="switch-combo<?php if (CHV\Settings::get('moderatecontent') == 0) { echo ' soft-hidden';} ?>">
              
              <div style="float:left;">
                <label for="moderatecontent_key">ModerateContent API Key</label>
                <input type="text" name="moderatecontent_key" id="moderatecontent_key" class="text-input" value="<?php echo CHV\Settings::get('moderatecontent_key', true); ?>" placeholder="">
                <div id="moderatecontent_key_error_msg" class="red-warning"></div>
                <div id="moderatecontent_key_msg" class="input-below" style="color:green;"></div>
              </div>
              <div style="float:left;max-width:100px;">
                <button id="moderatecontent_key_sign_up" class="btn btn-input" type="button" style="height: 50px;line-height: 18px; margin-left: 4px;margin-top: 7px;"><?php _se('Get FREE API Key'); ?></button>
              </div>
              <div style="clear:both;"></div>

              <div style="margin-top: 10px;">
                <label for="moderatecontent_action_block_upload">ModerateContent Action - Block Upload</label>
                <div class="c5 phablet-c1"><select type="text" name="moderatecontent_action_block_upload" id="moderatecontent_action_block_upload" class="text-input">
                  <?php echo CHV\Render\get_select_options_html([1 => _s('Enabled'), 0 => _s('Disabled')], CHV\Settings::get('moderatecontent_action_block_upload')); ?>
                </select></div>
              </div>

              <div style="margin-top: 10px;">
                <label for="moderatecontent_action_flag_nsfw">ModerateContent Action - Flag as NSFW (Adult Image) in Database</label>
                <div class="c5 phablet-c1"><select type="text" name="moderatecontent_action_flag_nsfw" id="moderatecontent_action_flag_nsfw" class="text-input">
                  <?php echo CHV\Render\get_select_options_html([1 => _s('Enabled'), 0 => _s('Disabled')], CHV\Settings::get('moderatecontent_action_flag_nsfw')); ?>
                </select></div>
              </div>

              <div style="margin-top: 10px;">
                <label for="moderatecontent_include_teen">Include (Teen Image) as blocked images</label>
                <div class="c5 phablet-c1"><select type="text" name="moderatecontent_include_teen" id="moderatecontent_include_teen" class="text-input">
                  <?php echo CHV\Render\get_select_options_html([1 => _s('Enabled'), 0 => _s('Disabled')], CHV\Settings::get('moderatecontent_include_teen')); ?>
                </select></div>
              </div>

            </div>
					</div>
          <?php 
              require_once CHV_APP_PATH_LIB_VENDOR . 'moderatecontent/moderatecontent.php';     
              echo CHV\ModerateContent::ajax_sign_up_script_render(); 
              ?>
			</div>
      <!-- MODERATECONTENT PLUGIN -->
      <!-- MODERATECONTENT PLUGIN -->
      <!-- MODERATECONTENT PLUGIN -->

			<?php
                } ?>

			<?php if (get_settings()['key'] == 'api') {

Step 5) Add new folder app/vendor/moderatecontent/.

Step 6) Create new file app/vendor/moderatecontent/moderatecontent.php and add the following to that file.

<?php
// MODERATECONTENT PLUGIN
// MODERATECONTENT PLUGIN
// MODERATECONTENT PLUGIN
namespace CHV;

class ModerateContent{
  public static function moderate_image($local_file){
    $response = (object)[];
    $response->moderation = Null;
    $response->error_msg = '';
    $response->error_code = 0;
    $response->local_file = $local_file;
    $response->key = Settings::get('moderatecontent_key');

    if (!file_exists($response->local_file)){
      $response->error_msg = 'Local file could not be found';
      $response->error_code = 1400;
    } else if (strlen($response->key) < 8) {
      $response->error_msg = 'Moderation API Key not found';
      $response->error_code = 1401;
    } else {

      $curl = curl_init();

      curl_setopt_array($curl, array(
        CURLOPT_URL => "http://api.moderatecontent.com/moderate/?key=".$response->key,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING => "",
        CURLOPT_MAXREDIRS => 10,
        CURLOPT_TIMEOUT => 3,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST => "POST",
        CURLOPT_POSTFIELDS => array('file'=> new \CURLFile($local_file)),
      ));

      $curl_response = curl_exec($curl);
      if ($curl_response === false){
        $response->error_msg = 'Moderation server could not be reached';
        $response->error_code = 1402;
      } else {
        $json = json_decode($curl_response);
        if ($json === null && json_last_error() !== JSON_ERROR_NONE) {
          $response->error_msg = 'Moderation error could be malformed image';
          $response->error_code = 1403;
        } else {
          $response->moderation = $json;
        }
      }
      curl_close($curl);
    }
    return $response;
  }

  public static function ajax_sign_up_script_render(){
    $current_admin_email = Settings::get('email_incoming_email');
    $html = "";
    $html .= '<script>';
    $html .= '(function() {';
    $html .= 'function moderatecontent_sign_up_ajax() {';
    $html .= '  var email = "'.$current_admin_email.'";';
    $html .= '  var url = "https://www.moderatecontent.com/documentation/api";';
    $html .= '  var xhttp = new XMLHttpRequest();';
    $html .= '  xhttp.onreadystatechange = function() {';
    $html .= '    if (this.readyState == 4 && this.status == 200) {';
    $html .= '      var json = JSON.parse(this.responseText);';
    $html .= '       if (json && json.api_key && json.api_key.length > 8){';
    $html .= '         document.getElementById("moderatecontent_key").value = json.api_key;';
    $html .= '         document.getElementById("moderatecontent_key_msg").innerHTML = "Success";';
    $html .= '       } else {';
    $html .= '         document.getElementById("moderatecontent_key_error_msg").innerHTML = "Could not sign you up at this time, please visit ModerateContent.com to manually get a key.";';
    $html .= '       }';
    $html .= '    }';
    $html .= '  };';
    $html .= '  xhttp.open("POST", url, true);';
    $html .= '  xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");';
    $html .= '  xhttp.send("email="+email+"&chevereto_source_flag=true");';
    $html .= '}';
    $html .= 'document.getElementById("moderatecontent_key_sign_up").addEventListener("click", function(){';
    $html .= '  moderatecontent_sign_up_ajax();';
    $html .= '});';
    $html .= '})();';
    $html .= '</script>';
    return $html;
  }
}

// MODERATECONTENT PLUGIN
// MODERATECONTENT PLUGIN
// MODERATECONTENT PLUGIN

Step 7) You need to add 4 new settings to the database table chv_settings (you might have a different table prefix)

a) moderatecontent
b) moderatecontent_key
c) moderatecontent_action_block_upload
d) moderatecontent_action_flag_nsfw

Should look something like this.

Step 8) Edit the settings for the plugin in the Chevereto dashboard. (Dashboard->Settings->External Services)

- use the "Get FREE API Key" to use the registered email for the plugin to get a key instantly.
- Action: Block Upload, will stop the upload from happening with an error message "This image contains adult content"
- Action: Flag as NSFW, will stop flag in the database the image as "NSFW" (Not safe for work) even if the user tries to edit the metadata.

Done) Should be working, if you have any issues please don't hesitate to contact us at info@moderatecontent.com. Good luck!.