Sindbad~EG File Manager
<?php
/**
* News Management Class for COP News Portal
*/
class News {
private $conn;
private $table_name = "news";
public function __construct($db) {
$this->conn = $db;
}
public function create($data) {
$query = "INSERT INTO " . $this->table_name . "
(title, location_id, description, content, written_by, category_id, user_id, featured_image, status)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
$stmt = $this->conn->prepare($query);
$result = $stmt->execute([
$data['title'],
$data['location_id'],
$data['description'] ?? '',
$data['content'],
$data['written_by'],
$data['category_id'] ?? null,
$data['user_id'],
$data['featured_image'] ?? '',
$data['status'] ?? 'draft'
]);
if ($result) {
$news_id = $this->conn->lastInsertId();
log_audit('CREATE', 'news', $news_id, null, $data);
return $news_id;
}
return false;
}
public function getById($id) {
$query = "SELECT n.*, c.name as category_name, u.name as author_name, l.name as location_name, l.type as location_type
FROM " . $this->table_name . " n
LEFT JOIN categories c ON n.category_id = c.id
LEFT JOIN users u ON n.user_id = u.id
LEFT JOIN locations l ON n.location_id = l.id
WHERE n.id = ?";
$stmt = $this->conn->prepare($query);
$stmt->execute([$id]);
return $stmt->fetch(PDO::FETCH_ASSOC);
}
public function getAll($filters = []) {
try {
$sql = "SELECT n.*, c.name as category_name, u.name as author_name, l.name as location_name, l.type as location_type
FROM news n
LEFT JOIN categories c ON n.category_id = c.id
LEFT JOIN users u ON n.user_id = u.id
LEFT JOIN locations l ON n.location_id = l.id
WHERE 1=1";
$params = [];
// Location-based access control
if (!empty($filters['user_location_type']) && !empty($filters['user_location_name'])) {
$accessibleLocations = $this->getAccessibleLocations($filters['user_location_type'], $filters['user_location_name']);
if (!empty($accessibleLocations)) {
$placeholders = str_repeat('?,', count($accessibleLocations) - 1) . '?';
$sql .= " AND (l.name IN ($placeholders))";
$params = array_merge($params, $accessibleLocations);
}
}
if (!empty($filters['status'])) {
$sql .= " AND n.status = ?";
$params[] = $filters['status'];
}
if (!empty($filters['category_id'])) {
$sql .= " AND n.category_id = ?";
$params[] = $filters['category_id'];
}
if (!empty($filters['location'])) {
$sql .= " AND n.location LIKE ?";
$params[] = '%' . $filters['location'] . '%';
}
if (!empty($filters['search'])) {
$sql .= " AND (n.title LIKE ? OR n.description LIKE ? OR n.content LIKE ?)";
$searchTerm = '%' . $filters['search'] . '%';
$params[] = $searchTerm;
$params[] = $searchTerm;
$params[] = $searchTerm;
}
if (!empty($filters['user_id'])) {
$sql .= " AND n.user_id = ?";
$params[] = $filters['user_id'];
}
$sql .= " ORDER BY n.created_at DESC";
if (!empty($filters['limit'])) {
$sql .= " LIMIT ?";
$params[] = $filters['limit'];
}
$stmt = $this->conn->prepare($sql);
$stmt->execute($params);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
error_log("News fetch error: " . $e->getMessage());
return [];
}
}
/**
* Get accessible locations for a user based on their location hierarchy
*/
private function getAccessibleLocations($userLocationType, $userLocationName) {
try {
$accessibleLocations = [$userLocationName, 'General', ''];
if ($userLocationType === 'assembly') {
// Assembly users can see their assembly, parent district, parent area
$stmt = $this->conn->prepare("
SELECT l1.name as assembly_name, l2.name as district_name, l3.name as area_name
FROM locations l1
LEFT JOIN locations l2 ON l1.parent_id = l2.id
LEFT JOIN locations l3 ON l2.parent_id = l3.id
WHERE l1.name = ? AND l1.type = 'assembly'
");
$stmt->execute([$userLocationName]);
$hierarchy = $stmt->fetch(PDO::FETCH_ASSOC);
if ($hierarchy) {
if ($hierarchy['district_name']) $accessibleLocations[] = $hierarchy['district_name'];
if ($hierarchy['area_name']) $accessibleLocations[] = $hierarchy['area_name'];
}
} elseif ($userLocationType === 'district') {
// District users can see their district and parent area
$stmt = $this->conn->prepare("
SELECT l1.name as district_name, l2.name as area_name
FROM locations l1
LEFT JOIN locations l2 ON l1.parent_id = l2.id
WHERE l1.name = ? AND l1.type = 'district'
");
$stmt->execute([$userLocationName]);
$hierarchy = $stmt->fetch(PDO::FETCH_ASSOC);
if ($hierarchy && $hierarchy['area_name']) {
$accessibleLocations[] = $hierarchy['area_name'];
}
}
return array_unique($accessibleLocations);
} catch (PDOException $e) {
error_log("Location hierarchy error: " . $e->getMessage());
return [$userLocationName, 'General', ''];
}
}
public function update($id, $data) {
$old_data = $this->getById($id);
$fields = [];
$values = [];
foreach ($data as $key => $value) {
$fields[] = "$key = ?";
$values[] = $value;
}
if (empty($fields)) {
return false;
}
$values[] = $id;
$query = "UPDATE " . $this->table_name . " SET " . implode(', ', $fields) . " WHERE id = ?";
$stmt = $this->conn->prepare($query);
$result = $stmt->execute($values);
if ($result) {
log_audit('UPDATE', 'news', $id, $old_data, $data);
}
return $result;
}
public function delete($id) {
$old_data = $this->getById($id);
$query = "DELETE FROM " . $this->table_name . " WHERE id = ?";
$stmt = $this->conn->prepare($query);
$result = $stmt->execute([$id]);
if ($result) {
log_audit('DELETE', 'news', $id, $old_data);
}
return $result;
}
public function incrementViews($id) {
$query = "UPDATE " . $this->table_name . " SET views = views + 1 WHERE id = ?";
$stmt = $this->conn->prepare($query);
return $stmt->execute([$id]);
}
public function getPublished($limit = 20, $offset = 0, $category_id = null, $location = null) {
$query = "SELECT n.id, n.title, n.location, n.description, n.views, n.created_at,
c.name as category_name, u.name as author_name
FROM " . $this->table_name . " n
LEFT JOIN categories c ON n.category_id = c.id
LEFT JOIN users u ON n.user_id = u.id
WHERE n.status = 'published'";
$params = [];
if ($category_id) {
$query .= " AND n.category_id = ?";
$params[] = $category_id;
}
if ($location) {
$query .= " AND n.location LIKE ?";
$params[] = "%$location%";
}
$query .= " ORDER BY n.created_at DESC LIMIT ? OFFSET ?";
$params[] = $limit;
$params[] = $offset;
$stmt = $this->conn->prepare($query);
$stmt->execute($params);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
public function search($keyword, $limit = 20, $offset = 0) {
$query = "SELECT n.id, n.title, n.location, n.description, n.views, n.created_at,
c.name as category_name, u.name as author_name
FROM " . $this->table_name . " n
LEFT JOIN categories c ON n.category_id = c.id
LEFT JOIN users u ON n.user_id = u.id
WHERE n.status = 'published'
AND (n.title LIKE ? OR n.description LIKE ? OR n.content LIKE ? OR n.location LIKE ?)
ORDER BY n.created_at DESC LIMIT ? OFFSET ?";
$searchTerm = "%$keyword%";
$stmt = $this->conn->prepare($query);
$stmt->execute([$searchTerm, $searchTerm, $searchTerm, $searchTerm, $limit, $offset]);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
public function getTotalCount($status = null, $user_id = null) {
$query = "SELECT COUNT(*) as total FROM " . $this->table_name;
$conditions = [];
$params = [];
if ($status) {
$conditions[] = "status = ?";
$params[] = $status;
}
if ($user_id) {
$conditions[] = "user_id = ?";
$params[] = $user_id;
}
if (!empty($conditions)) {
$query .= " WHERE " . implode(' AND ', $conditions);
}
$stmt = $this->conn->prepare($query);
$stmt->execute($params);
$result = $stmt->fetch(PDO::FETCH_ASSOC);
return $result['total'];
}
public function getRecentNews($limit = 5) {
$query = "SELECT id, title, location, created_at
FROM " . $this->table_name . "
WHERE status = 'published'
ORDER BY created_at DESC LIMIT ?";
$stmt = $this->conn->prepare($query);
$stmt->execute([$limit]);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
public function getStatsByLocation() {
$query = "SELECT location, COUNT(*) as count
FROM " . $this->table_name . "
WHERE status = 'published'
GROUP BY location
ORDER BY count DESC";
$stmt = $this->conn->prepare($query);
$stmt->execute();
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
}
?>
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists