���Root Mod By V1rus_Alfa
User / IP
:
216.73.217.78
Host / Server
:
195.214.235.115 / npln.ir
System
:
Linux damavand.pws-dns.net 5.14.0-503.35.1.el9_5.x86_64 #1 SMP PREEMPT_DYNAMIC Fri Apr 4 05:23:43 EDT 2025 x86_64
Command
|
Upload
|
Mass Deface
|
Create
:
/
home2
/
cutunixc
/
repositories
/
portal-cutunix
/
app
/
Livewire
/
Components
/
Viewing: SearchableSelectBox.php
<?php namespace App\Livewire\Components; use Livewire\Component; class SearchableSelectBox extends Component { public $search = ''; public $selected = null; public $selectedLabel = ''; public $placeholder = 'Select an option...'; public $isOpen = false; public $name = 'searchable_select'; public $limit = 50; // Database configuration public $model; public $valueField = 'id'; public $labelField = 'name'; public $searchFields = []; public $orderBy = null; public $orderDirection = 'asc'; public $whereConditions = []; public $withRelations = []; protected $listeners = ['clickOutside' => 'closeDropdown']; public function mount($config = []) { $this->model = $config['model'] ?? null; $this->valueField = $config['value_field'] ?? 'id'; $this->labelField = $config['label_field'] ?? 'name'; $this->searchFields = $config['search_fields'] ?? [$this->labelField]; $this->placeholder = $config['placeholder'] ?? $this->placeholder; $this->name = $config['name'] ?? $this->name; $this->limit = $config['limit'] ?? 50; $this->orderBy = $config['order_by'] ?? $this->labelField; $this->orderDirection = $config['order_direction'] ?? 'asc'; $this->whereConditions = $config['where'] ?? []; $this->withRelations = $config['with'] ?? []; $defaultOrder = 'id'; // Safe fallback if (isset($config['order_by'])) { $this->orderBy = $config['order_by']; } else { // If labelField is a getter attribute or relation, use safe default if ($this->isGetterAttribute($this->labelField) || strpos($this->labelField, '.') !== false) { $this->orderBy = $defaultOrder; } else { $this->orderBy = $this->labelField; } } // Set initial selected value if (isset($config['selected'])) { $this->setSelectedValue($config['selected']); } } public function updatedSearch() { $this->isOpen = true; } public function selectOption($key, $value) { $this->selected = $key; $this->selectedLabel = $value; $this->search = ''; $this->isOpen = false; $this->dispatch('optionSelected', $key, $value); } public function openDropdown() { $this->isOpen = true; } public function closeDropdown() { $this->isOpen = false; $this->search = ''; } public function setSelectedValue($value) { if ($value && $this->model) { $record = $this->model::with($this->withRelations)->find($value); if ($record) { $this->selected = $this->getFieldValue($record, $this->valueField); $this->selectedLabel = $this->getFieldValue($record, $this->labelField); } } } /** * Check if a field is a getter attribute */ private function isGetterAttribute($field) { if (strpos($field, '.') !== false) { return false; // Relations are not getter attributes } if (!class_exists($this->model)) { return false; } $instance = new $this->model(); $method = 'get' . str_replace('_', '', ucwords($field, '_')) . 'Attribute'; return method_exists($instance, $method); } /** * Get field value supporting relations and getter attributes */ private function getFieldValue($record, $field) { // Handle nested relations (e.g., 'user.profile.name') if (strpos($field, '.') !== false) { $parts = explode('.', $field); $value = $record; foreach ($parts as $part) { if ($value) { $value = $value->{$part}; } } return $value; } // Handle getter attributes or direct fields return $record->{$field}; } /** * Apply search conditions including relations */ private function applySearchConditions($query) { if (empty($this->search)) { return; } $query->where(function ($q) { foreach ($this->searchFields as $field) { $this->addSearchCondition($q, $field); } }); } /** * Add search condition for a field (supports relations) */ private function addSearchCondition($query, $field) { if (strpos($field, '.') !== false) { // Handle relation search (e.g., 'user.name', 'category.parent.name') $parts = explode('.', $field); $relation = array_slice($parts, 0, -1); $column = end($parts); $query->orWhereHas(implode('.', $relation), function ($q) use ($column) { $q->where($column, 'LIKE', '%' . $this->search . '%'); }); } else { // Handle direct field search (skip getter attributes in SQL) if (!$this->isGetterAttribute($field)) { $query->orWhere($field, 'LIKE', '%' . $this->search . '%'); } } } /** * Apply ordering - improved to handle relations properly */ private function applyOrdering($query) { if (!$this->orderBy) { return; } // Skip ordering if it's a getter attribute - we'll sort in PHP later if ($this->isGetterAttribute($this->orderBy)) { return; } if (strpos($this->orderBy, '.') !== false) { // Handle relation ordering using whereHas with orderBy $parts = explode('.', $this->orderBy); $relationPath = implode('.', array_slice($parts, 0, -1)); $column = end($parts); // Use a subquery approach for ordering by relations $model = new $this->model(); $relation = $this->getRelationInstance($model, $relationPath); if ($relation) { $relatedTable = $relation->getRelated()->getTable(); $foreignKey = $relation->getForeignKeyName(); $ownerKey = $relation->getOwnerKeyName(); $query->leftJoin($relatedTable, function ($join) use ($foreignKey, $ownerKey, $model, $relatedTable) { $join->on($model->getTable() . '.' . $foreignKey, '=', $relatedTable . '.' . $ownerKey); })->orderBy($relatedTable . '.' . $column, $this->orderDirection); } } else { // Handle direct field ordering $query->orderBy($this->orderBy, $this->orderDirection); } } /** * Get relation instance from model using relation path */ private function getRelationInstance($model, $relationPath) { $relations = explode('.', $relationPath); $currentModel = $model; foreach ($relations as $relation) { if (method_exists($currentModel, $relation)) { $relationInstance = $currentModel->{$relation}(); if ($relationInstance instanceof Relation) { $currentModel = $relationInstance->getRelated(); } else { return null; } } else { return null; } } return $currentModel->{end($relations)}(); } /** * Sort collection by getter attribute if needed */ private function sortByGetterAttribute($collection) { if (!$this->isGetterAttribute($this->orderBy)) { return $collection; } $sorted = $collection->sortBy(function ($item) { return $this->getFieldValue($item, $this->orderBy); }); return $this->orderDirection === 'desc' ? $sorted->reverse() : $sorted; } public function getOptionsProperty() { if (!$this->model) { return collect(); } $query = $this->model::query(); // Apply relationships - always include relations used in labelField and searchFields $allRelations = $this->withRelations; // Add relations from labelField if (strpos($this->labelField, '.') !== false) { $parts = explode('.', $this->labelField); $relation = implode('.', array_slice($parts, 0, -1)); if (!in_array($relation, $allRelations)) { $allRelations[] = $relation; } } // Add relations from searchFields foreach ($this->searchFields as $field) { if (strpos($field, '.') !== false) { $parts = explode('.', $field); $relation = implode('.', array_slice($parts, 0, -1)); if (!in_array($relation, $allRelations)) { $allRelations[] = $relation; } } } if (!empty($allRelations)) { $query->with($allRelations); } // Apply where conditions foreach ($this->whereConditions as $condition) { if (is_array($condition) && count($condition) >= 2) { $query->where($condition[0], $condition[1], $condition[2] ?? null); } } // Apply search $this->applySearchConditions($query); // Apply ordering (skip if it's a getter attribute) $this->applyOrdering($query); // Limit results $query->limit($this->limit); $results = $query->get(); // Sort by getter attribute if needed if ($this->isGetterAttribute($this->orderBy)) { $results = $this->sortByGetterAttribute($results); if ($this->orderDirection === 'desc') { $results = $results->reverse(); } } return $results; } public function render() { return view('livewire.components.searchable-select'); } }
Coded With 💗 by
0x6ick Mod By V1rus_Alfa