_setTbl('formlogs'); } public function isDeleteByCancel() { return false; } public function canUnpublish() { return true; } public function unpublishEtaps( $taskId ) { WaicFrame::_()->getModule('workspace')->getModel('tasks')->updateTask($taskId, array('status' => 6)); return false; } public function publishResults( $taskId, $publish ) { WaicFrame::_()->getModule('workspace')->getModel('tasks')->updateTask($taskId, array('status' => 4)); return false; } public function clearEtaps( $taskId, $ids = false, $withContent = true ) { /*if ($withContent) { WaicFrame::_()->getModule('workspace')->getModel('history')->deleteHistory($taskId); $query = 'DELETE t FROM @__chatlogs t WHERE NOT EXISTS(SELECT 1 FROM @__history h WHERE h.id=t.his_id)'; WaicDb::query($query); }*/ return true; } public function createTable() { if (!WaicDb::exist('@__formlogs')) { require_once ABSPATH . 'wp-admin/includes/upgrade.php'; dbDelta(WaicDb::prepareQuery("CREATE TABLE IF NOT EXISTS `@__formlogs` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `his_id` INT NOT NULL DEFAULT 0, `question` MEDIUMTEXT NOT NULL, `answer` MEDIUMTEXT NOT NULL, `file` MEDIUMTEXT NOT NULL, PRIMARY KEY (`id`), INDEX `his_id` (`his_id`) ) DEFAULT CHARSET=utf8mb4;")); } } public function getFields() { if (is_null($this->_fields)) { $this->_fields = array( 'email' => __('Email', 'ai-copilot-content-generator'), 'input' => __('Input', 'ai-copilot-content-generator'), 'textarea' => __('Textarea', 'ai-copilot-content-generator'), 'number' => __('Number', 'ai-copilot-content-generator'), 'date' => __('Date', 'ai-copilot-content-generator'), 'dropdown' => __('Select (Dropdown)', 'ai-copilot-content-generator'), 'checkboxes' => __('Checkboxes', 'ai-copilot-content-generator'), 'radio' => __('Radio Buttons', 'ai-copilot-content-generator'), //'file' => __('File Upload', 'ai-copilot-content-generator'), ); } return $this->_fields; } public function getDisplayOutputModes() { $modes = array( 'below' => __('Below Form', 'ai-copilot-content-generator'), 'custom' => __('Custom CSS Selector', 'ai-copilot-content-generator'), ); return $modes; } public function getRepeatOutputModes() { $modes = array( 'replace' => __('Replace', 'ai-copilot-content-generator'), 'append' => __('Append', 'ai-copilot-content-generator'), ); return $modes; } public function getNotificationsSendModes() { $modes = array( 'before' => __('Before AI', 'ai-copilot-content-generator'), 'after' => __('After AI success', 'ai-copilot-content-generator'), 'error' => __('On AI error', 'ai-copilot-content-generator'), ); return $modes; } public function getIfOperators() { $operators = array( 'equals' => __('Equals', 'ai-copilot-content-generator'), 'not_equals' => __('Not Equals', 'ai-copilot-content-generator'), 'contains' => __('Contains', 'ai-copilot-content-generator'), 'not_contains' => __('Not Contains', 'ai-copilot-content-generator'), 'greater' => __('Greater Than', 'ai-copilot-content-generator'), 'less' => __('Less Than', 'ai-copilot-content-generator'), 'empty' => __('Is Empty', 'ai-copilot-content-generator'), 'not_empty' => __('Is Not Empty', 'ai-copilot-content-generator'), ); return $operators; } public function getThenActions() { $actions = array( 'show' => __('Show', 'ai-copilot-content-generator'), 'hide' => __('Hide', 'ai-copilot-content-generator'), 'enable' => __('Enable', 'ai-copilot-content-generator'), 'disable' => __('Disable', 'ai-copilot-content-generator'), 'value' => __('Set value', 'ai-copilot-content-generator'), ); return $actions; } public function getLabelVarsList( $fields, $label ) { $list = array(); if (!empty($fields)) { foreach ($fields as $id => $data) { $list[$id] = $label . '_' . $id; if (!empty($data['title'])) { $len = strlen($data['title']); $list[$id] .= ' ' . ( $len > 10 ? WaicUtils::mbsubstr($data['title'], 0, 10) . '...' : $data['title'] ); } } } return $list; } public function controlTaskParameters( $params, &$error = '', $taskId = 0 ) { if (!WaicFrame::_()->isPro()) { $forms = WaicFrame::_()->getModule('workspace')->getModel('tasks')->getTaskByParams(array('feature' => 'forms', 'additionalCondition' => 'id!=' . ((int) $taskId)), 'id'); if ($forms && !is_null($forms)) { $error = __('To get access to creating more than one form, you need to purchase and receive the Pro version of the plugin.', 'ai-copilot-content-generator'); return false; } } $apiParams = WaicUtils::getArrayValue($params, 'api', array(), 2); if (false === WaicUtils::checkEmptyApiKeys($apiParams, $error)) { return false; } /*$fields = WaicUtils::getArrayValue($params, 'fields', array(), 2); if (empty($fields)) { $error = __('Fields are not specified', 'ai-copilot-content-generator'); return false; } $outputs = WaicUtils::getArrayValue($params, 'outputs', array(), 2); if (empty($outputs)) { $error = __('Outputs are not specified', 'ai-copilot-content-generator'); return false; }*/ $submits = WaicUtils::getArrayValue($params, 'submits', array(), 2); if (empty($submits)) { $error = __('Submits are not specified', 'ai-copilot-content-generator'); return false; } return empty($error); } public function convertTaskParameters( $params, $toDB = true ) { $rules = WaicUtils::getArrayValue($params, 'rules', array(), 2); if (!empty($rules)) { foreach ($rules as $id => $data) { $ifs = WaicUtils::getArrayValue($data, 'ifs', array(), 2); $ifsNew = empty($ifs) ? array() : array_values($ifs); $rules[$id]['ifs'] = $ifsNew; $thens = WaicUtils::getArrayValue($data, 'thens', array(), 2); $thensNew = empty($thens) ? array() : array_values($thens); $rules[$id]['thens'] = $thensNew; $elses = WaicUtils::getArrayValue($data, 'elses', array(), 2); $elsesNew = empty($elses) ? array() : array_values($elses); $rules[$id]['elses'] = $elsesNew; } $params['rules'] = $rules; } return WaicDispatcher::applyFilters('convertTaskParameters', $params, $toDB); } public function preparePrompt( $prompt, $data ) { preg_match_all('/\$\{([^{}]+)\}/', $prompt, $selectors); //preg_match_all('/(?getModule('workspace'); $task = $workspace->getModel('tasks')->getTask($taskId); if (!$task || empty($task)) { return array('answer' => __('Form not found.', 'ai-copilot-content-generator'), 'error' => 1); } $params = WaicUtils::getArrayValue($task, 'params', array(), 2); $file = ''; if ($files) { $api = WaicUtils::getArrayValue($params, 'api', array(), 2); $files = $this->getFileString($files, WaicUtils::getArrayValue($api, 'max_file_size', 5, 1) * 1048576); if (!empty($files['error'])) { return array('answer' => $files['error'], 'error' => 1); } $file = $files['file']; } if (isset($options['user_id'])) { $user = empty($options['user_id']) ? false : get_user_by('id', (int) $options['user_id']); } else { $user = wp_get_current_user(); } $userId = $user ? $user->ID : 0; $isGuest = empty($userId); $ip = isset($options['ip']) ? $options['ip'] : WaicUtils::getRealUserIp(); $hisModel = $workspace->getModel('history'); $submits = WaicUtils::getArrayValue($params, 'submits', array(), 2); $submit = WaicUtils::getArrayValue($submits, $subId, array(), 2); if (empty($submit)) { return array('answer' => __('Submit not found.', 'ai-copilot-content-generator'), 'error' => 1); } $data['FORM_ID'] = $taskId; $data['TIMESTAMP'] = date_i18n('Y-m-d H:i:s'); //date('Y-m-d H:i:s'); $sendWebhook = WaicUtils::getArrayValue($submit, 'webhook', 0, 1) == 1; $webhookSend = $sendWebhook ? WaicUtils::getArrayValue($submit, 'w_send') : ''; if ('before' == $webhookSend) { $this->sendWebhook($submit, $data); } $sendEmail = WaicUtils::getArrayValue($submit, 'email', 0, 1) == 1; $emailSend = $sendEmail ? WaicUtils::getArrayValue($submit, 'e_send') : ''; if ('before' == $emailSend) { $this->sendMails($submit, $data); } $prompt = WaicUtils::getArrayValue($submit, 'prompt'); if (empty($prompt)) { return array('answer' => __('Prompt not found.', 'ai-copilot-content-generator'), 'error' => 1); } $prompt = $this->preparePrompt($prompt, $data); $apiOptions = WaicUtils::getArrayValue($params, 'api', array(), 2); $aiProvider = $workspace->getModel('aiprovider')->getInstance($apiOptions); if (!$aiProvider) { return false; } $aiProvider->init( $taskId, $userId, $ip, 0, false ); $aiProvider->setSessionId('form-' . (int) $taskId . '-' . substr(md5($userId . '|' . $ip . '|' . $prompt), 0, 16)); $history = array( 'task_id' => $taskId, 'user_id' => $userId, 'session_id' => 'form-' . (int) $taskId . '-' . substr(md5($userId . '|' . $ip . '|' . $prompt), 0, 16), 'ip' => $ip, 'mode' => 0, 'status' => 2, 'tokens' => 0, ); if ($aiProvider->setApiOptions($apiOptions)) { $opts = array('prompt' => $prompt); $result = $aiProvider->getText($opts); } else { $result = array( 'error' => 1, 'msg' => WaicFrame::_()->getLastError(), 'his_id' => $hisModel->saveHistory($history), ); } $newLog = array( 'his_id' => $result['his_id'], 'question' => $this->controlText(str_replace(PHP_EOL, '
', $prompt)), 'answer' => $this->controlText($result['error'] ? $result['msg'] : $result['data'], true), 'file' => $file, 'error' => $result['error'], ); if (!empty($result['his_id'])) { $this->insert($newLog); } $error = $newLog['error']; if ($sendEmail || $sendWebhook) { $data['AI_RESPONSE'] = $newLog['answer']; if (($error && 'error' == $emailSend) || (empty($error) && 'after' == $emailSend)) { $this->sendMails($submit, $data); } if (($error && 'error' == $webhookSend) || (empty($error) && 'after' == $webhookSend)) { $this->sendWebhook($submit, $data); } } return array('answer' => $newLog['answer'], 'error' => $error); } public function controlText( $str, $mark = false ) { if ( !$str ) { return ''; } if ($mark) { $str = WaicUtils::markdownToHtml($str); } $str = str_replace(array('```html', '```'), array('', ''), $str); return str_replace(array("'"), array('`'), $str); //return preg_replace('/\r\n|\r|\n/', '
', str_replace(array("'"), array('`'), $str)); } private function getHistoryPreview( $value, $length = 50 ) { $value = wp_strip_all_tags((string) $value); if (WaicUtils::mbstrlen($value) <= $length) { return $value; } return WaicUtils::mbsubstr($value, 0, $length) . '...'; } public function getHistory( $params ) { $length = WaicUtils::getArrayValue($params, 'length', 10, 1); $start = WaicUtils::getArrayValue($params, 'start', 0, 1); $search = esc_sql(WaicUtils::getArrayValue(WaicUtils::getArrayValue($params, 'search', array(), 2), 'value')); $taskId = WaicUtils::getArrayValue($params, 'task_id', 0, 1); $where = array(); $args = array(); if (!empty($search)) { global $wpdb; $like = '%' . $wpdb->esc_like($search) . '%'; $where[] = 'h.created LIKE %s'; $where[] = 'u.user_login LIKE %s'; $where[] = 'h.ip LIKE %s'; $where[] = 'l.question LIKE %s'; $where[] = 'l.answer LIKE %s'; $args = array($like, $like, $like, $like, $like); } $query = 'SELECT l.id, h.created as dd, h.user_id, u.user_login, h.ip, h.tokens, l.question, l.answer' . ' FROM @__history as h' . ' INNER JOIN @__formlogs l ON (l.his_id=h.id)' . ' LEFT JOIN #__users u ON (u.id=h.user_id)' . ' WHERE h.task_id=' . ( (int) $taskId ) . ( empty($where) ? '' : ' AND (' . implode(' OR ', $where) . ')' ); $order = WaicUtils::getArrayValue($params, 'order', array(), 2); $orderBy = 0; $sortOrder = 'desc'; $orders = array('id', 'dd', 'user_login', 'ip', 'tokens', 'question', 'answer'); if (isset($order[0])) { $orderBy = WaicUtils::getArrayValue($order[0], 'column', $orderBy, 1); $sortOrder = WaicUtils::getArrayValue($order[0], 'dir', $sortOrder); } $query .= ' ORDER BY ' . $orders[$orderBy] . ( 'desc' == strtolower($sortOrder) ? ' desc' : ' asc' ); $logs = WaicDb::get($query, 'all', ARRAY_A, $args); $totalCount = empty($logs) ? 0 : count($logs); if ($length > 0) { if ($start >= $totalCount) { $start = 0; } $end = $start + $length; } else { $end = $totalCount; } $rows = array(); if ($totalCount > 0) { $view = __('view', 'ai-copilot-content-generator'); $guest = __('guest', 'ai-copilot-content-generator'); for ($i = $start; $i < $end; $i++) { if (!isset($logs[$i])) { break; } $log = $logs[$i]; $question = (string) $log['question']; $answer = (string) $log['answer']; $questionPreview = $this->getHistoryPreview($question); $answerPreview = $this->getHistoryPreview($answer); $userLabel = empty($log['user_id']) ? $guest : (string) $log['user_login']; $rows[] = array( '
' . esc_html($log['id']) . '
', '
' . esc_html($log['dd']) . '
', '
' . esc_html($userLabel) . '
', '
' . esc_html($log['ip']) . '
', '
' . esc_html($log['tokens']) . '
', '
' . esc_html($questionPreview) . '
', '
' . esc_html($answerPreview) . '
', '' . esc_html($view) . '', ); } } return array( 'data' => $rows, 'total' => $totalCount, ); } public function sendMails( $submit, $data ) { $to = WaicUtils::getArrayValue($submit, 'e_to'); $subject = WaicUtils::getArrayValue($submit, 'e_subject'); $message = WaicUtils::getArrayValue($submit, 'e_message'); $subject = $this->preparePrompt($subject, $data); $message = $this->preparePrompt($message, $data); $to = trim($this->preparePrompt($to, $data)); if (empty($to) || empty($subject) || empty($message)) { return; } $headers = array( 'Content-type: text/html; charset=utf-8', 'Content-Transfer-Encoding: 8bit', 'From: ' . get_option( 'woocommerce_email_from_name' ) . ' <' . get_option( 'woocommerce_email_from_address' ) . '>' ); if (!wp_mail($to, $subject, $message, $headers)) { WaicFrame::_()->pushError(__('Error by sending email', 'ai-copilot-content-generator')); return false; } return true; } public function sendWebhook( $submit, $data ) { $url = WaicUtils::getArrayValue($submit, 'w_url'); $headers = WaicUtils::getArrayValue($submit, 'w_headers'); $message = html_entity_decode(stripslashes(WaicUtils::getArrayValue($submit, 'w_message'))); if (empty($url) || empty($message)) { return; } $url = $this->preparePrompt($url, $data); $headers = $this->preparePrompt($headers, $data); $message = $this->preparePrompt($message, $data); if (!empty($headers)) { $paars = explode(PHP_EOL, $headers); $headers = array(); foreach ($paars as $paar) { $p = explode(':', $paar); if (count($p)) { $headers[trim($p[0])] = trim($p[1]); } } } if (empty($headers)) { $headers = array('Content-Type' => 'application/json'); } $options = array( 'headers' => $headers, 'method' => 'POST', 'body' => $message, ); WaicFrame::_()->saveDebugLogging(array('endpoint' => $url, 'Send WEBHOOK' => $options)); $response = wp_remote_request($url, $options); if (is_wp_error($response)) { WaicFrame::_()->pushError($response->get_error_message()); return false; } } }