'Save Credentials', 'label' => 'Save Changes', 'icon' => 'floppy-disk', 'action' => [$this, 'saveCredentials'] ], [ 'name' => 'Clear Credentials', 'icon' => 'broom', 'action' => [$this, 'clearCredentials'] ], ]; foreach ($actions as $a) { $this->addAction($a['name'], $a['action'], $a['slug']??null, $a['icon']??null, $a['label']??null); } } public function addAction(string $name, callable $callback, ?string $slug = null, ?string $icon = null, ?string $label = null):void { $action = new AdminActions($name, $callback); if (!is_null($slug)) { $action->setSlug($slug); } if (!is_null($icon)) { $action->setIcon($icon); } if (!is_null($label)) { $action->setLabel($label); } $this->actions[$action->getSlug()] = $action; } /** * @param string $action * @param mixed|null $data * @return array [ * 'success' => {bool}, * 'message' => {string} optional message, * 'data' => {mixed} optional data to return * ] */ public function processAction(string $action, mixed $data = null):array { if (!array_key_exists($action, $this->actions)) { $this->logError('processAction', 'Attempted action not setup: '.print_r(['action' => $action, 'service' => $this->service_name], true)); return $this->response(false, 'Attempted action not set up'); } $theAction = $this->actions[$action]; if (!$theAction->checkPermission()) { $this->logError('processAction', 'User has no capabilities to perform this action: '.print_r(['action' => $action, 'service' => $this->service_name], true)); return $this->response(false, 'Insufficient permissions'); } $result = $theAction->handleCallback($data); if (is_wp_error($result)) { $this->logError('processAction', $result->get_error_message()); return $this->response(false, $result->get_error_message()); } return $result; } public function renderConnection(bool $return = false):string { if ($this->userID && !JVB()->userCanConnect($this->service_name, $this->userID)) { return ''; } $credentials = $this->loadCredentials(); $isConnected = !empty($credentials); $meta = ''; if ($isConnected && array_key_exists('updated_at', $credentials) && $credentials['updated_at'] > 0) { $meta = sprintf( '
Last updated: %s ago
', human_time_diff($credentials['updated_at']) ); } $form = sprintf( '

%s

%s %sSet Up
%s', $this->service_name, $isConnected ? 'connected' : 'disconnected', esc_attr($this->service_name), esc_html($this->title), $isConnected ? '●' : '○', $isConnected ? '' : 'Not ', $meta, ); if (!empty($this->instructions)) { $form .= sprintf( ' Instructions
    %s
', $isConnected ? '' : ' open', implode('',array_map(function($el) { return sprintf('
  • %s
  • ', $el); }, $this->instructions)) ); } if (current_user_can('manage_options')) { $form .= sprintf( '
    Setup %s %s
    ', $isConnected ? '' : ' open', $this->outputFields($this->credentialFields), method_exists($this, 'renderWebhookUrl') ? $this->renderWebhookUrl() : '' ); } if (method_exists($this, 'renderOAuthConnectionForm')) { $form .= $this->renderOAuthConnectionForm(); } if (!empty($this->optionalFields) || $this->hasExtraOptions) { $form .= '
    '; if (!empty($this->optionalFields)) { $form .= sprintf( '
    Advanced Settings%s
    ', $this->outputFields($this->optionalFields) ); } if ($this->hasExtraOptions) { $form .= sprintf( 'More Settings', $this->determineOptionPage() ); } $form .= '
    '; } $form .= $this->outputActionButtons(); $form .= ''; if (!$return) { echo $form; } return $form; } protected function outputActionButtons():string { return sprintf('
    %s
    ',implode('', array_map(function($action) { $label = ''; if (!empty ($action->getIcon())) { $label .= $this->outputIcon($action->getIcon()); } $label .= $action->getLabel(); return sprintf( '', $action->getSlug, $action->getName(), empty($action->getConfirm()) ? '' : ' data-confirm="'.$action->getConfirm().'"', $label ); }, array_filter($this->actions, function ($action) { return $action->checkPermission(); })))); } protected function outputFields(array $fields):string { $credentials = $this->loadCredentials(); $fields = array_filter($fields, function ($field) { return $field->checkPermission(); }); return implode('', array_map(function($f) use ($credentials) { $value = array_key_exists($f->name, $credentials) ? $credentials[$f->name] : ''; $config = $f->getConfig(); if (!empty($value)) { $config['readonly'] = true; } $config['base'] = $this->service_name.'_'; return Form::render($f->name, $value, $f->getConfig()); }, $fields)); } public function addField(string $name, string $label, string $type, callable|string|bool $permission):Field { $field = new Field($name, $label, $type, $permission); $this->fields[$name] = $field; return $field; } public function setFieldRequired(string $name):bool { if (!array_key_exists($name, $this->fields)) { return false; } $this->fields[$name]->setRequired(); return true; } }