diff --git a/src/app/baseclasses/BaseRepository.php b/src/app/baseclasses/BaseRepository.php new file mode 100644 index 0000000000000000000000000000000000000000..bf1b0efb077952582bc94c6712c9ca542e536b72 --- /dev/null +++ b/src/app/baseclasses/BaseRepository.php @@ -0,0 +1,231 @@ +<?php + +require_once SRC_ROOT_PATH . "/app/core/PDOHandler.php"; + +abstract class BaseRepository +{ + protected static $instance; + protected $pdo; + protected $tableName = ''; + + protected function __construct() + { + $this->pdo = PDOInstance::getInstance()->getPDO(); + } + + public static function getInstance() + { + if (!isset(self::$instance)) { + self::$instance = new static(); + } + return self::$instance; + } + + public function getPDO() + { + return $this->pdo; + } + + public function getAll() + { + $sql = "SELECT * FROM $this->tableName"; + return $this->pdo->query($sql); + } + + public function countRow($where = []) { + $sql = "SELECT COUNT(*) FROM $this->tableName"; + + if (count($where) > 0) { + $sql .= " WHERE "; + $sql .= implode(" AND ", array_map(function ($key, $value) { + if ($value[2] == 'LIKE') { + return "$key LIKE :$key"; + } + + return "$key = :$key"; + }, array_keys($where), array_values($where))); + } + $stmt = $this->pdo->prepare($sql); + foreach ($where as $key => $value) { + $stmt->bindValue(":$key", $value[0], $value[1]); + if ($value[2] == 'LIKE') { + $stmt->bindValue(":$key", "%$value[0]%", $value[1]); + } else { + $stmt->bindValue(":$key", $value[0], $value[1]); + } + } + + $stmt->execute(); + return $stmt->fetchColumn(); + } + + public function findAll( + $where = [], + $order = null, + $pageNo = null, + $pageSize = null, + $isDesc = false, + ) { + $sql = "SELECT * FROM $this->tableName "; + + if (count($where) > 0) { + $sql .= "WHERE "; + $sql .= implode(" AND ", array_map(function ($key, $value) { + if ($key == "judul") { + return "(judul LIKE :$key OR penyanyi LIKE :$key OR YEAR(tanggal_terbit) LIKE :$key)"; + } + + if ($value[2] == 'LIKE') { + return "$key LIKE :$key"; + } + + return "$key = :$key"; + }, array_keys($where), array_values($where))); + } + + if ($order) { + $sql .= " ORDER BY $order"; + } + + if ($isDesc) { + $sql .= " DESC"; + } + + if ($pageSize && $pageNo) { + $sql .= " LIMIT :pageSize"; + $sql .= " OFFSET :offset"; + } + + $stmt = $this->pdo->prepare($sql); + foreach ($where as $key => $value) { + if ($value[2] == 'LIKE') { + $stmt->bindValue(":$key", "%$value[0]%", $value[1]); + } else { + $stmt->bindValue(":$key", $value[0], $value[1]); + } + } + + if ($pageSize && $pageNo) { + $offset = ($pageNo - 1) * $pageSize; + + $stmt->bindValue(":pageSize", $pageSize, PDO::PARAM_INT); + $stmt->bindValue(":offset", $offset, PDO::PARAM_INT); + } + + + + + + $stmt->execute(); + return $stmt->fetchAll(); + } + + public function findOne($arrParams) + { + $sql = "SELECT * FROM $this->tableName WHERE "; + $i = 0; + foreach ($arrParams as $key => $value) { + $sql .= "$key = :$key"; + if ($i < count($arrParams) - 1) { + $sql .= " AND "; + } + $i++; + } + + $stmt = $this->pdo->prepare($sql); + foreach ($arrParams as $key => $value) { + $stmt->bindValue(":$key", $value[0], $value[1]); + } + + $stmt->execute(); + return $stmt->fetch(); + } + + public function insert($model, $arrParams) + { + $sql = "INSERT INTO $this->tableName ("; + $i = 0; + foreach ($arrParams as $key => $value) { + $sql .= "$key"; + if ($i < count($arrParams) - 1) { + $sql .= ", "; + } + $i++; + } + $sql .= ") VALUES ("; + $i = 0; + foreach ($arrParams as $key => $value) { + $sql .= ":$key"; + if ($i < count($arrParams) - 1) { + $sql .= ", "; + } + $i++; + } + $sql .= ")"; + + $stmt = $this->pdo->prepare($sql); + foreach ($arrParams as $key => $value) { + $stmt->bindValue(":$key", $model->get($key), $value); + } + + $stmt->execute(); + return $this->pdo->lastInsertId(); + } + + public function update($model, $arrParams) + { + $sql = "UPDATE $this->tableName SET "; + $i = 0; + foreach ($arrParams as $key => $value) { + $sql .= "$key = :$key"; + if ($i < count($arrParams) - 1) { + $sql .= ", "; + } + $i++; + } + $primaryKey = $model->get('_primary_key'); + $sql .= " WHERE $primaryKey = :primaryKey"; + + $stmt = $this->pdo->prepare($sql); + foreach ($arrParams as $key => $value) { + $stmt->bindValue(":$key", $model->get($key), $value); + } + $stmt->bindValue(":primaryKey", $model->get($primaryKey), PDO::PARAM_INT); + + $stmt->execute(); + return $stmt->rowCount(); + } + + public function delete($model) + { + $sql = "DELETE FROM $this->tableName WHERE "; + $primaryKey = $model->get('_primary_key'); + $sql .= "$primaryKey = :primaryKey"; + + $stmt = $this->pdo->prepare($sql); + $stmt->bindValue(":primaryKey", $model->get($primaryKey), PDO::PARAM_INT); + + $stmt->execute(); + return $stmt->rowCount(); + } + + public function getNLastRow($N) + { + $sql = "SELECT COUNT(*) FROM $this->tableName"; + $stmt = $this->pdo->prepare($sql); + $stmt->execute(); + $count = $stmt->fetchColumn(); + + if ($count < $N) { + $N = $count; + } + + $offset = $count - $N; + $sql = "SELECT * FROM $this->tableName LIMIT :limit OFFSET :offset"; + $stmt = $this->pdo->prepare($sql); + $stmt->bindValue(":limit", $N, PDO::PARAM_INT); + $stmt->bindValue(":offset", $offset, PDO::PARAM_INT); + $stmt->execute(); + return $stmt->fetchAll(); + } +} \ No newline at end of file diff --git a/src/app/baseclasses/BaseService.php b/src/app/baseclasses/BaseService.php new file mode 100644 index 0000000000000000000000000000000000000000..92c31403602e59a44ee0f0183fed3f9feed81547 --- /dev/null +++ b/src/app/baseclasses/BaseService.php @@ -0,0 +1,16 @@ +<?php + +abstract class BaseService { + protected static $instance; + protected $repository; + + protected function __construct() { + } + + public static function getInstance() { + if (!isset(self::$instance)) { + self::$instance = new static(); + } + return self::$instance; + } +} \ No newline at end of file diff --git a/src/app/clients/SocmedSoapClient.php b/src/app/clients/SocmedSoapClient.php new file mode 100644 index 0000000000000000000000000000000000000000..95a4988b1b3ea9cbf090a7bd55b8ba1364fa9885 --- /dev/null +++ b/src/app/clients/SocmedSoapClient.php @@ -0,0 +1,81 @@ +<?php + +require_once SRC_ROOT_PATH . "/utils/SoapWrapper.php"; + +class SocmedSoapClient +{ + private static $instance; + private $client; + + private function __construct() + { + $opts = array( + 'http' => array( + 'header' => 'Authorization: ' . getenv("MONOLITHIC_SOAP_API_KEY")) + ); + + $params = array( + 'encoding' => 'UTF-8', + 'soap_version' => SOAP_1_2, + 'trace' => 1, + 'exceptions' => 1, + 'connection_timeout' => 180, + 'stream_context' => stream_context_create($opts), + ); + + $this->client = new SoapWrapper($_ENV['WSDL_URL'], $params); + } + + public static function getInstance() + { + if (!isset(self::$instance)) { + self::$instance = new static(); + } + return self::$instance; + } + + public function requestUnlocking($socmed_id, $link_code) + { + $res = $this->client->call("requestUnlocking", array( + 'arg0' => $socmed_id, + 'arg1' => null, + 'arg2' => $link_code, + )); + return $res; + } + + public function getUnlocking() + { + $res = $this->client->call("getUnlocking", null); + return $res; + } + + public function getUnlockingBySocmedId($socmed_id) + { + $response = self::getInstance()->getUnlockingBySocmedId( + array( + "socmed_id" => $socmed_id, + ) + ); + return $response; + } + + public function acceptUnlocking($socmed_id, $link_code) + { + $res = $this->client->call("acceptUnlocking", array( + 'arg0' => $socmed_id, + 'arg1' => null, + 'arg2' => $link_code, + )); + return $res; + } + + public function rejectUnlocking($socmed_id, $link_code) + { + $res = $this->client->call("rejectUnlocking", array( + 'arg0' => $socmed_id, + 'arg1' => $link_code, + )); + return $res; + } +} diff --git a/src/app/controllers/Unlocking/UnlockingController.php b/src/app/controllers/Unlocking/UnlockingController.php new file mode 100644 index 0000000000000000000000000000000000000000..5b734d1d9725f2d20207b30492c225e095055062 --- /dev/null +++ b/src/app/controllers/Unlocking/UnlockingController.php @@ -0,0 +1,31 @@ +<?php + +require_once SRC_ROOT_PATH . "/app/services/UnlockingService.php"; +require_once SRC_ROOT_PATH . "/app/baseclasses/BaseController.php"; + +class UnlockingController extends BaseController { + protected static $instance; + + private function __construct($srv) + { + parent::__construct($srv); + } + + public static function getInstance() + { + if (!isset(self::$instance)) { + self::$instance = new static( + UnlockingService::getInstance() + ); + } + return self::$instance; + } + + public function post($urlParams) { + + $socmed_id = $_SESSION['id']; + $link_code = $_SESSION['username']; + + return $this->srv->requestUnlocking($socmed_id, $link_code); + } +} diff --git a/src/app/models/UnlockingModel.php b/src/app/models/UnlockingModel.php new file mode 100644 index 0000000000000000000000000000000000000000..7cd27407917eefb57dc56a763f42258b8e6520b7 --- /dev/null +++ b/src/app/models/UnlockingModel.php @@ -0,0 +1,33 @@ +<?php + +require_once SRC_ROOT_PATH . "/baseclasses/BaseModel.php"; + +class SubscriptionModel extends BaseModel +{ + public $socmed_id; + public $dashboard_id; + public $link_code; + + public function __construct() + { + $this->_primary_key = ["socmed_id"]; + return $this; + } + + public function constructFromArray($array) + { + $this->socmed_id = $array["socmed_id"]; + $this->dashboard_id = $array["dashboard_id"]; + $this->link_code = ($array["link_code"]); + return $this; + } + + public function toResponse() + { + return array( + "socmed_id" => $this->socmed_id, + "dashboard_id" => $this->dashboard_id, + "link_code" => $this->link_code, + ); + } +} diff --git a/src/app/repositories/UnlockingRespository.php b/src/app/repositories/UnlockingRespository.php new file mode 100644 index 0000000000000000000000000000000000000000..9eae8c60479a3468cc217e5305918e4fa68c474e --- /dev/null +++ b/src/app/repositories/UnlockingRespository.php @@ -0,0 +1,59 @@ +<?php + +require_once SRC_ROOT_PATH . "/baseclasses/BaseRepository.php"; + +class UnlockingRepository extends BaseRepository{ + protected static $instance; + + private function __construct() { + parent::__construct(); + } + + public static function getInstance() { + if (!isset(self::$instance)) { + self::$instance = new static(); + } + return self::$instance; + } + + public function getAllUnlockings() { + $sql = "SELECT * FROM unlocking"; + $stmt = $this->pdo->prepare($sql); + $stmt->execute(); + return $stmt->fetchAll(); + } + + public function getUnlocking($socmed_id, $dashboard_id) { + $sql = "SELECT * FROM unlocking WHERE socmed_id = :socmed_id AND dashboard_id = :dashboard_id"; + $stmt = $this->pdo->prepare($sql); + + $stmt->bindParam(':socmed_id', $socmed_id, PDO::PARAM_INT); + $stmt->bindParam(':dashboard_id', $dashboard_id, PDO::PARAM_INT); + + $stmt->execute(); + return $stmt->fetchAll(); + } + + public function getAcceptedUnlockingBySocmedID($socmed_id) { + $sql = "SELECT * FROM unlocking WHERE socmed_id = :socmed_id and dashboard_id IS NOT NULL"; + $stmt = $this->pdo->prepare($sql); + + $stmt->bindParam(':socmed_id', $socmed_id, PDO::PARAM_INT); + + $stmt->execute(); + return $stmt->fetchAll(); + } + + public function insertUnlocking($socmed_id, $dashboard_id, $link_code) { + $sql = "INSERT INTO unlocking (socmed_id, dashboard_id, link_code) VALUES (:socmed_id, :subscriber_id, :link_code)"; + $stmt = $this->pdo->prepare($sql); + + $stmt->bindParam(':socmed_id', $socmed_id, PDO::PARAM_INT); + $stmt->bindParam(':dashboard_id', $dashboard_id, PDO::PARAM_INT); + $stmt->bindParam(':link_code', $link_code, PDO::PARAM_STR); + + $stmt->execute(); + return $stmt->rowCount(); + } +} + diff --git a/src/app/services/UnlockingService.php b/src/app/services/UnlockingService.php new file mode 100644 index 0000000000000000000000000000000000000000..ef823d69bec7fee9ca27ba2296d172038247e33b --- /dev/null +++ b/src/app/services/UnlockingService.php @@ -0,0 +1,73 @@ +<?php + +require_once PROJECT_ROOT_PATH . "/src/bases/BaseService.php"; +require_once PROJECT_ROOT_PATH . "/src/utils/SoapWrapper.php"; +require_once PROJECT_ROOT_PATH . "/src/clients/SocmedSoapClient.php"; +require_once PROJECT_ROOT_PATH . "/src/models/UnlockingModel.php"; +require_once PROJECT_ROOT_PATH . "/src/repositories/UnlockingRepository.php"; + +class UnlockingService extends BaseSrv { + protected static $instance; + private $client; + + private function __construct($client) { + parent::__construct(); + $this->client = $client; + } + + public static function getInstance() { + if (!isset(self::$instance)) { + self::$instance = new static( + SocmedSoapClient::getInstance() + ); + } + return self::$instance; + } + + public function getAcceptedUnlockingBySocmedId($socmedId) { + $unlocksSQL = UnlockingRepository::getInstance()->getAcceptedUnlockingBySocmedId($socmedId); + + $unlocks = []; + foreach ($unlocksSQL as $unlockSQL) { + $unlock = new UnlockingModel(); + $unlocks[] = $unlock->constructFromArray($unlockSQL); + } + return $unlocks; + } + + public function update($socmed_id, $dashboard_id, $link_code) { + return UnlockingnRepository::getInstance() + ->updateUnlocking($socmed_id, $dashboard_id, $link_code); + } + + public function requestUnlocking($socmed_id, $link_code) { + $resp = $this->client->requestUnlocking($socmed_id, $link_code); + UnlockingRepository::getInstance()->insertUnlocking($socmed_id, null, $link_code); + + return $resp; + } + + public function getSoapUnlocking() { + return $this->client->getUnlocking(); + } + + public function getUnlocking() { + $sqlRes = UnlockingRepository::getInstance()->getAllUnlockings(); + + $unlocks = []; + foreach ($sqlRes as $unlockSQL) { + $unlock = new UnlockingModel(); + $unlocks[] = $unlock->constructFromArray($unlockSQL); + } + + return $subs; + } + + public function acceptUnlocking($socmed_id, $link_code) { + return $this->client->acceptUnlocking($socmed_id, $link_code); + } + + public function rejectUnlocking($socmed_id, $link_code) { + return $this->client->rejectUnlocking($socmed_id, $link_code); + } +} diff --git a/src/app/utils/Logger.php b/src/app/utils/Logger.php new file mode 100644 index 0000000000000000000000000000000000000000..308ddb757588c4651d2d39f901c05a4064e5211b --- /dev/null +++ b/src/app/utils/Logger.php @@ -0,0 +1,174 @@ +<?php + +class Logger +{ + protected static $log_file; + protected static $file; + protected static $options = [ + 'dateFormat' => 'd-M-Y', + 'logFormat' => 'H:i:s d-M-Y' + ]; + private static $instance; + private static $logdir = PROJECT_ROOT_PATH . '/logs'; + + public static function createLogFile() + { + $time = date(static::$options['dateFormat']); + static::$log_file = static::$logdir . "/log-{$time}.txt"; + + if (!file_exists(static::$logdir)) { + mkdir(static::$logdir, 0777, true); + } + + if (!file_exists(static::$log_file)) { + fopen(static::$log_file, 'w') or exit("Can't create {static::log_file}!"); + } + + if (!is_writable(static::$log_file)) { + throw new Exception("ERROR: Unable to write to file!", 1); + } + } + + public static function setOptions($options = []) + { + static::$options = array_merge(static::$options, $options); + } + + public static function info($message, array $context = []) + { + $bt = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 1); + + static::writeLog([ + 'message' => $message, + 'bt' => $bt, + 'severity' => 'INFO', + 'context' => $context + ]); + } + + public static function notice($message, array $context = []) + { + $bt = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 1); + + static::writeLog([ + 'message' => $message, + 'bt' => $bt, + 'severity' => 'NOTICE', + 'context' => $context + ]); + } + + public static function debug($message, array $context = []) + { + $bt = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 1); + + static::writeLog([ + 'message' => $message, + 'bt' => $bt, + 'severity' => 'DEBUG', + 'context' => $context + ]); + } + + public static function warning($message, array $context = []) + { + $bt = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 1); + + static::writeLog([ + 'message' => $message, + 'bt' => $bt, + 'severity' => 'WARNING', + 'context' => $context + ]); + } + + public static function error($message, array $context = []) + { + $bt = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 1); + + static::writeLog([ + 'message' => $message, + 'bt' => $bt, + 'severity' => 'ERROR', + 'context' => $context + ]); + } + + public static function fatal($message, array $context = []) + { + $bt = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 1); + + static::writeLog([ + 'message' => $message, + 'bt' => $bt, + 'severity' => 'FATAL', + 'context' => $context + ]); + } + + public static function writeLog($args = []) + { + static::createLogFile(); + + if (!is_resource(static::$file)) { + static::openLog(); + } + + $time = date(static::$options['logFormat']); + + $context = json_encode($args['context']); + + $caller = array_shift($args['bt']); + $btLine = $caller['line']; + $btPath = $caller['file']; + + $path = static::absToRelPath($btPath); + + $timeLog = is_null($time) ? "[N/A] " : "[{$time}] "; + $pathLog = is_null($path) ? "[N/A] " : "[{$path}] "; + $lineLog = is_null($btLine) ? "[N/A] " : "[{$btLine}] "; + $severityLog = is_null($args['severity']) ? "[N/A]" : "[{$args['severity']}]"; + $messageLog = is_null($args['message']) ? "N/A" : "{$args['message']}"; + $contextLog = empty($args['context']) ? "" : "{$context}"; + + fwrite(static::$file, "{$timeLog}{$pathLog}{$lineLog}: {$severityLog} - {$messageLog} {$contextLog}" . PHP_EOL); + + static::closeFile(); + } + + private static function openLog() + { + $openFile = static::$log_file; + static::$file = fopen($openFile, 'a') or exit("Can't open $openFile!"); + } + + public static function closeFile() + { + if (static::$file) { + fclose(static::$file); + } + } + + public static function absToRelPath($pathToConvert) + { + $pathAbs = str_replace(['/', '\\'], '/', $pathToConvert); + $documentRoot = str_replace(['/', '\\'], '/', $_SERVER['DOCUMENT_ROOT']); + return $_SERVER['SERVER_NAME'] . str_replace($documentRoot, '', $pathAbs); + } + + protected function __construct() + { + } + + public static function getInstance() + { + if (is_null(self::$instance)) { + self::$instance = new self(); + } + return self::$instance; + } + + private function __destruct() + { + } +} diff --git a/src/app/utils/SoapWrapper.php b/src/app/utils/SoapWrapper.php new file mode 100644 index 0000000000000000000000000000000000000000..d4d7511b17cb828811e8b4d5664fec0d1dfb5825 --- /dev/null +++ b/src/app/utils/SoapWrapper.php @@ -0,0 +1,33 @@ +<?php + +class SoapWrapper { + public function __construct($wsdl) { + try { + $this->soapClient = new SoapClient($wsdl,array( + "exceptions" => 0, + "trace" => 1, + "encoding" => "UTF-8", + 'stream_context' => stream_context_create(array( + 'http' => array( + 'header' => 'Authorization: Bearer ' . $_ENV['API_KEY'], + ), + )), + )); + } catch (Exception $e) { + Logger::error("SoapWrapper: Error while creating SoapClient: " . $e->getMessage()); + $this->soapClient = null; + } + } + + public function call($functionName, $params) { + $res = null; + + if (!isset($params)) { + $res = $this->soapClient->$functionName(); + } else { + $res = $this->soapClient->$functionName($params); + } + + return json_encode($res); + } +} \ No newline at end of file