Init(Core): create and add project

This commit is contained in:
2026-05-02 01:58:10 +03:30
commit 4928901a08
14 changed files with 1022 additions and 0 deletions

28
admin/admin.php Normal file
View File

@@ -0,0 +1,28 @@
<?php
// Prevent direct access
if (!defined('ABSPATH')) {
exit;
}
use Sodino\Controllers\AdminController;
use Sodino\Repositories\RuleRepository;
// Initialize admin
$ruleRepository = new RuleRepository();
$adminController = new AdminController($ruleRepository);
// Add menu
add_action('admin_menu', [$adminController, 'addMenu']);
// Enqueue admin assets
add_action('admin_enqueue_scripts', function($hook) {
if (strpos($hook, 'sodino') === false) {
return;
}
wp_enqueue_style('sodino-admin', plugin_dir_url(__FILE__) . 'css/admin.css', [], SODINO_VERSION);
});
// Handle delete for any Sodino admin page
if (isset($_GET['page']) && strpos($_GET['page'], 'sodino') === 0 && isset($_GET['action']) && $_GET['action'] === 'delete') {
add_action('admin_init', [$adminController, 'handleDelete']);
}

View File

@@ -0,0 +1,132 @@
<?php
if (!defined('ABSPATH')) {
exit;
}
if (!class_exists('WP_List_Table')) {
require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
}
class Sodino_Rules_List_Table extends WP_List_Table {
private $repository;
private $items_per_page = 20;
public function __construct($repository) {
parent::__construct([
'singular' => 'sodino_rule',
'plural' => 'sodino_rules',
'ajax' => false,
]);
$this->repository = $repository;
}
public function get_columns() {
return [
'cb' => '<input type="checkbox" />',
'name' => __('عنوان قانون', 'sodino'),
'condition_type' => __('نوع کاربر', 'sodino'),
'action_value' => __('درصد تخفیف', 'sodino'),
'enabled' => __('وضعیت', 'sodino'),
'actions' => __('عملیات', 'sodino'),
];
}
protected function get_sortable_columns() {
return [
'name' => ['name', true],
];
}
protected function column_cb($item) {
return sprintf('<input type="checkbox" name="rule_ids[]" value="%d" />', $item->id);
}
public function get_bulk_actions() {
return [
'delete' => __('حذف گروهی', 'sodino'),
];
}
public function column_actions($item) {
$edit_url = admin_url('admin.php?page=sodino-add-rule&action=edit&id=' . $item->id);
$delete_url = wp_nonce_url(admin_url('admin.php?page=sodino-rules&action=delete&id=' . $item->id), 'delete_rule');
return sprintf(
'<a href="%s">%s</a> | <a href="%s" onclick="return confirm(\'%s\');">%s</a>',
esc_url($edit_url),
esc_html__('ویرایش', 'sodino'),
esc_url($delete_url),
esc_js(__('آیا از حذف این قانون مطمئن هستید؟', 'sodino')),
esc_html__('حذف', 'sodino')
);
}
public function column_name($item) {
$edit_url = admin_url('admin.php?page=sodino-add-rule&action=edit&id=' . $item->id);
$title = sprintf('<strong><a href="%s">%s</a></strong>', esc_url($edit_url), esc_html($item->name));
return $title;
}
public function column_condition_type($item) {
$value = __('کاربر جدید', 'sodino');
if ($item->condition_value === 'returning') {
$value = __('کاربر بازگشتی', 'sodino');
}
return esc_html($value);
}
public function column_action_value($item) {
return sprintf('%s %%', esc_html($item->action_value));
}
public function column_enabled($item) {
return $item->enabled ? __('فعال', 'sodino') : __('غیرفعال', 'sodino');
}
public function column_default($item, $column_name) {
switch ($column_name) {
case 'name':
case 'condition_type':
case 'action_value':
case 'enabled':
case 'actions':
return '';
default:
return '';
}
}
public function prepare_items() {
$columns = $this->get_columns();
$hidden = [];
$sortable = $this->get_sortable_columns();
$this->_column_headers = [$columns, $hidden, $sortable];
$this->process_bulk_action();
$all_items = $this->repository->getAll();
$current_page = $this->get_pagenum();
$total_items = count($all_items);
$this->items = array_slice($all_items, ($current_page - 1) * $this->items_per_page, $this->items_per_page);
$this->set_pagination_args([
'total_items' => $total_items,
'per_page' => $this->items_per_page,
'total_pages' => ceil($total_items / $this->items_per_page),
]);
}
public function process_bulk_action() {
if ('delete' === $this->current_action()) {
$rule_ids = isset($_POST['rule_ids']) ? array_map('intval', $_POST['rule_ids']) : [];
if (!empty($rule_ids) && check_admin_referer('bulk-' . $this->_args['plural'])) {
foreach ($rule_ids as $id) {
$this->repository->delete($id);
}
}
}
}
}

22
admin/css/admin.css Normal file
View File

@@ -0,0 +1,22 @@
.wrap {
direction: rtl;
}
.sodino-admin-table th,
.sodino-admin-table td {
text-align: right;
}
.page-title-action {
float: left;
}
.rtl .page-title-action {
float: left;
}
input.regular-text,
select.regular-text,
input.small-text {
direction: rtl;
}

54
admin/views/rule-form.php Normal file
View File

@@ -0,0 +1,54 @@
<?php
// Prevent direct access
if (!defined('ABSPATH')) {
exit;
}
?>
<div class="wrap">
<h1><?php echo $rule->id ? __('ویرایش قانون', 'sodino') : __('افزودن قانون جدید', 'sodino'); ?></h1>
<form method="post">
<?php wp_nonce_field('gheymatyar_save_rule', 'gheymatyar_rule_nonce'); ?>
<table class="form-table">
<tr>
<th scope="row"><label for="name"><?php _e('عنوان قانون', 'sodino'); ?></label></th>
<td><input type="text" name="name" id="name" value="<?php echo esc_attr($rule->name); ?>" class="regular-text" required></td>
</tr>
<tr>
<th scope="row"><label for="condition_type"><?php _e('نوع شرط', 'sodino'); ?></label></th>
<td>
<select name="condition_type" id="condition_type" class="regular-text" required>
<option value="user_type" <?php selected($rule->condition_type, 'user_type'); ?>><?php _e('نوع کاربر', 'sodino'); ?></option>
</select>
</td>
</tr>
<tr>
<th scope="row"><label for="condition_value"><?php _e('نوع کاربر', 'sodino'); ?></label></th>
<td>
<select name="condition_value" id="condition_value" class="regular-text" required>
<option value="new" <?php selected($rule->condition_value, 'new'); ?>><?php _e('کاربر جدید', 'sodino'); ?></option>
<option value="returning" <?php selected($rule->condition_value, 'returning'); ?>><?php _e('کاربر بازگشتی', 'sodino'); ?></option>
</select>
</td>
</tr>
<tr>
<th scope="row"><label for="action_type"><?php _e('نوع عملیات', 'sodino'); ?></label></th>
<td>
<select name="action_type" id="action_type" class="regular-text" required>
<option value="discount_percent" <?php selected($rule->action_type, 'discount_percent'); ?>><?php _e('درصد تخفیف', 'sodino'); ?></option>
</select>
</td>
</tr>
<tr>
<th scope="row"><label for="action_value"><?php _e('درصد تخفیف', 'sodino'); ?></label></th>
<td><input type="number" name="action_value" id="action_value" value="<?php echo esc_attr($rule->action_value); ?>" min="0" max="100" step="0.01" class="small-text" required> %</td>
</tr>
<tr>
<th scope="row"><label for="enabled"><?php _e('وضعیت', 'sodino'); ?></label></th>
<td><label><input type="checkbox" name="enabled" id="enabled" value="1" <?php checked($rule->enabled, 1); ?>> <?php _e('فعال باشد', 'sodino'); ?></label></td>
</tr>
</table>
<?php submit_button($rule->id ? __('به‌روزرسانی قانون', 'sodino') : __('افزودن قانون', 'sودino'), 'primary'); ?>
</form>
</div>

View File

@@ -0,0 +1,15 @@
<?php
// Prevent direct access
if (!defined('ABSPATH')) {
exit;
}
?>
<div class="wrap">
<h1><?php _e('قوانین قیمت‌گذاری', 'sodino'); ?></h1>
<a href="<?php echo admin_url('admin.php?page=sodino-add-rule'); ?>" class="page-title-action"><?php _e('افزودن قانون جدید', 'sodino'); ?></a>
<form method="post">
<?php $rulesTable->display(); ?>
</form>
</div>

12
admin/views/settings.php Normal file
View File

@@ -0,0 +1,12 @@
<?php
// Prevent direct access
if (!defined('ABSPATH')) {
exit;
}
?>
<div class="wrap">
<h1><?php _e('تنظیمات قیمت‌یار', 'sodino'); ?></h1>
<div class="notice notice-info">
<p><?php _e('در اینجا تنظیمات افزونه در آینده قرار خواهد گرفت.', 'sodino'); ?></p>
</div>
</div>