diff --git a/phptodo/TodoApp.php b/phptodo/TodoApp.php new file mode 100644 index 0000000..9a7c95d --- /dev/null +++ b/phptodo/TodoApp.php @@ -0,0 +1,93 @@ +app = AppFactory::create(); + $this->util = new Util(); + + $repository = new TodoRepository(); + $todoController = new TodoController($repository); + + $this->app->add(new CorsMiddleware( + [ + "origin" => ["*"], + "methods" => ["GET", "POST", "PUT", "PATCH", "DELETE"], + "headers.allow" => ["Authorization", "Content-Type"], + "headers.expose" => [], + "credentials" => true, + "cache" => 0 + ] + )); + + $this->app->get('/todos', function (Request $request, Response $response, $args) use ($todoController) { + + $todos = $todoController->getAllTodos(); + $response->getBody()->write(json_encode($todos)); + $response = $response->withStatus(200, 'OK'); + return $response; + }); + + // Map the GET /todos/{id} endpoint to the getTodoById method + $this->app->get('/todos/{id}', function (Request $request, Response $response, $args) use ($todoController) { + $id = $args['id']; + $todo = $todoController->getTodoById($id); + $response->getBody()->write(json_encode($todo)); + $response = $response->withStatus(200, 'OK'); + return $response; + }); + + // Map the POST /todos endpoint to the createTodo method + $this->app->post('/todos', function (Request $request, Response $response, $args) use ($todoController) { + + $data = $request->getBody(); + $todo = $todoController->createTodo($data); + $response->getBody()->write(json_encode($todo)); + $response = $response->withStatus(200, 'OK'); + return $response->withHeader('Content-Type', 'application/json'); + }); + + // Map the PUT /todos/{id} endpoint to the updateTodoById method + $this->app->put('/todos', function (Request $request, Response $response, $args) use ($todoController) { + $data = $request->getBody(); + $todo = $todoController->updateTodoById($data); + $response->getBody()->write(json_encode($todo)); + $response = $response->withStatus(201, 'OK'); + return $response; + }); + + // Map the DELETE /todos/{id} endpoint to the deleteTodoById method + $this->app->delete('/todos/{id}', function (Request $request, Response $response, $args) use ($todoController) { + $id = $args['id']; + $todoController->deleteTodoById($id); + $response->getBody()->write(json_encode(['id' => $id])); + $response = $response->withStatus(200, 'OK'); + return $response; + }); + } + + public function run() + { + $this->app->run(); + $this->util->logEvent(); + } +} + +$todoApp = new TodoApp(); + +// Run the application +$todoApp->run(); diff --git a/phptodo/Util.php b/phptodo/Util.php new file mode 100644 index 0000000..34c956a --- /dev/null +++ b/phptodo/Util.php @@ -0,0 +1,63 @@ +statsig = new StatsigServer("secret-9lbe9aax4FWPyJiLrKfo8GAj1cXX2UUqoDBcG4B7rKW", $options); + $this->user = StatsigUser::withUserID("php_user"); + $this->user->setEmail("user_php@statsig.com"); + $this->user->setCountry("IN"); + } + + public function run() + { + $config = $this->statsig->getConfig($this->user, "warning_banner"); + print_r($config); + $jsonString = json_encode($config); + print_r($jsonString); + } + + public function getExperiment() + { + $todo_experiment = $this->statsig->getExperiment($this->user, "item_sorting"); + print_r($todo_experiment); + print_r($todo_experiment->getName()); + print_r($todo_experiment->getValue()); + + $jsonString = json_encode($todo_experiment); + print_r($jsonString); + } + + public function logEvent() + { + $event = new StatsigEvent("TODO_CREATE"); + $event->setUser($this->user); + $event->setValue("TODO"); + $event->setMetadata(array("title" => "TODO_1")); + $this->statsig->logEvent($event); + } + + public function flush() + { + $this->statsig->flush(); + } +} + +?> \ No newline at end of file diff --git a/phptodo/composer.json b/phptodo/composer.json new file mode 100644 index 0000000..cea1757 --- /dev/null +++ b/phptodo/composer.json @@ -0,0 +1,19 @@ +{ + "name": "statsig/phptodo", + "description": "A PHP Todo project", + "type": "project", + "require": { + "statsig/statsigsdk": "^2.2", + "doctrine/dbal": "^3.7", + "slim/slim": "4.*", + "tuupola/cors-middleware": "*", + "psr/http-message": "^1.0", + "selective/basepath": "*" + + }, + "autoload": { + "psr-4": { + "Statsig\\Phptodo\\": "src/" + } + } +} diff --git a/phptodo/readme.md b/phptodo/readme.md new file mode 100644 index 0000000..58a3952 --- /dev/null +++ b/phptodo/readme.md @@ -0,0 +1,144 @@ +#### TODO project in PHP + +##### PHP version + +```PHP 8.2.12 (cli) (``` + +##### Run the project +Navigate till TodoApp.php file in project and execute command + +```php -S localhost:8080 .\TodoApp.php ``` + +### API Structure + +The Todo App CRUD API is a set of endpoints that allow users to perform CRUD (Create, Read, Update, Delete) operations on todo items in the Todo App. + +The API includes the following endpoints: + +- `GET /todos`: Retrieves a list of all todo items. +- `GET /todos/{id}`: Retrieves a specific todo item by its ID. +- `POST /todos`: Creates a new todo item. +- `PUT /todos`: Updates an existing todo item. +- `DELETE /todos/{id}`: Deletes a todo item. + +Each endpoint accepts and returns JSON data. + +Sample CURL requests with responses for the Todo App CRUD API: + +1. Retrieve a list of all todo items: + + ```bash + curl -s http://localhost:8080/todos + ``` + + Response: + + ```json + [ + { + "id": 1, + "task": "task1", + "description": "", + "completed": false, + "edited": false, + "lastViewed": false, + "serialNumber": 1, + "createdDate": "2023-10-18T07:12:31.830Z", + "modifiedDate": "2023-10-18T07:12:31.830Z" + }, + { + "id": 2, + "task": "task2", + "description": "", + "completed": false, + "edited": false, + "lastViewed": false, + "serialNumber": 2, + "createdDate": "2023-10-18T07:12:34.746Z", + "modifiedDate": "2023-10-18T07:12:34.746Z" + }, + .... +] + ``` + +2. Retrieve a specific todo item by its ID: + + ```bash + curl -s http://localhost:8080/todos/{id} + ``` + + Response: + + ```json + { + "id": 1, + "task": "task1", + "description": "", + "completed": false, + "edited": false, + "lastViewed": false, + "serialNumber": 1, + "createdDate": "2023-10-18T07:12:31.830Z", + "modifiedDate": "2023-10-18T07:12:31.830Z" + } + ``` + +3. Create a new todo item: + + ```bash + curl -s POST -H "Content-Type: application/json" -d '{"serialNumber": 10,"task": "task9","completed": false,"description": "","edited": false,"createdDate": "2023-10-06T10:41:11.806Z","modifiedDate": "2023-10-06T10:41:11.806Z","lastViewed": false}' http://localhost:8080/todos + ``` + + Response: + + ```json + { + "id": 7, + "task": "task9", + "description": "", + "completed": 0, + "edited": 0, + "serialNumber": 10, + "lastViewed": 0, + "createdDate": "2023-10-06T10:41:11.806Z", + "modifiedDate": "2023-10-06T10:41:11.806Z" +} + ``` + +4. Update an existing todo item: + + ```bash + curl -s PUT -H "Content-Type: application/json" -d '{"serialNumber": 10,"task": "task9","completed": false,"description": "","edited": true,"createdDate": "2023-10-06T10:41:11.806Z","modifiedDate": "2023-10-06T10:41:11.806Z","lastViewed": true, "id":7}' http://localhost:8080/todos + ``` + + Response: + + ```json + { + "serialNumber": 10, + "task": "task9", + "completed": false, + "description": "", + "edited": true, + "createdDate": "2023-10-06T10:41:11.806Z", + "modifiedDate": "2023-10-06T10:41:11.806Z", + "lastViewed": true, + "id": 7 +} + ``` + +5. Delete a todo item: + + ```bash + curl -X DELETE http://localhost:8080/todos/{id} + ``` + + Response: + + ```json + { + "id": "7" + } + ``` + + diff --git a/phptodo/src/TodoController.php b/phptodo/src/TodoController.php new file mode 100644 index 0000000..913a2c9 --- /dev/null +++ b/phptodo/src/TodoController.php @@ -0,0 +1,82 @@ +repository = $repository; + } + + public function getAllTodos() + { + $todos = $this->repository->getAllTodos(); + return $todos; + } + + public function getTodoById($id) + { + $todo = $this->repository->getTodoById($id); + if ($todo) { + return $todo; + } + return $this->notFound(); + } + + public function createTodo() + { + $input = $this->getJsonInput(); + $todo = $this->repository->createTodo( + $input['task'] ?? '', + $input['description'] ?? '', + $input['completed'] ?? false, + $input['edited'] ?? false, + $input['serialNumber'] ?? 0, + $input['lastViewed'] ?? '', + $input['createdDate'] ?? '', + $input['modifiedDate'] ?? '' + ); + return $todo; + } + + public function updateTodoById() + { + $input = $this->getJsonInput(); + $todo = $this->repository->updateTodo( + $input['id'] ?? 0, + $input['task'] ?? '', + $input['description'] ?? '', + $input['completed'] ?? false, + $input['edited'] ?? false, + $input['serialNumber'] ?? 0, + $input['lastViewed'] ?? '', + $input['createdDate'] ?? '', + $input['modifiedDate'] ?? '' + ); + return $todo; + } + + public function deleteTodoById($id) + { + $this->repository->deleteTodo($id); + return ['id' => $id]; + } + + public function sendJsonResponse($data) + { + header('Content-Type: application/json'); + return json_encode($data); + } + + public function getJsonInput() + { + $input = file_get_contents('php://input'); + return json_decode($input, true) ?? []; + } + + public function notFound() + { + header('HTTP/1.1 404 Not Found'); + echo '404 Not Found'; + } +} diff --git a/phptodo/src/todo.php b/phptodo/src/todo.php new file mode 100644 index 0000000..9ce390a --- /dev/null +++ b/phptodo/src/todo.php @@ -0,0 +1,26 @@ +id = $id; + $this->task = $task; + $this->description = $description; + $this->completed = $completed; + $this->edited = $edited; + $this->serialNumber = $serialNumber; + $this->lastViewed = $lastViewed; + $this->createdDate = $createdDate; + $this->modifiedDate = $modifiedDate; + } +} diff --git a/phptodo/src/todorepository.php b/phptodo/src/todorepository.php new file mode 100644 index 0000000..ac9ce86 --- /dev/null +++ b/phptodo/src/todorepository.php @@ -0,0 +1,87 @@ +filePath)) { + touch($this->filePath); + } + } + + public function getAllTodos() + { + $todos = json_decode(file_get_contents($this->filePath), true); + return $todos; + } + + public function getTodoById($id) + { + $todos = json_decode(file_get_contents($this->filePath), true); + foreach ($todos as $todo) { + if ($todo['id'] == $id) { + return $todo; + } + } + return null; + } + + public function createTodo($task, $description, $completed, $edited, $serialNumber, $lastViewed, $createdDate, $modifiedDate) + { + $todos = json_decode(file_get_contents($this->filePath), true); + $count = count($todos ?? []); + + $newTodo = [ + 'id' => $count + 1, + 'task' => $task, + 'description' => $description, + 'completed' => $completed, + 'edited' => $edited, + 'serialNumber' => $serialNumber, + 'lastViewed' => $lastViewed, + 'createdDate' => $createdDate, + 'modifiedDate' => $modifiedDate + ]; + $todos[] = $newTodo; + file_put_contents($this->filePath, json_encode($todos)); + return $newTodo; + } + + public function updateTodo($id, $task, $description, $completed, $edited, $serialNumber, $lastViewed, $createdDate, $modifiedDate) + { + $todos = json_decode(file_get_contents($this->filePath), true); + $tempTodo = null; + error_log($id); + foreach ($todos as &$todo) { + if ($todo['id'] == $id) { + $todo['task'] = $task; + $todo['description'] = $description; + $todo['completed'] = $completed; + $todo['edited'] = $edited; + $todo['serialNumber'] = $serialNumber; + $todo['lastViewed'] = $lastViewed; + $todo['createdDate'] = $createdDate; + $todo['modifiedDate'] = $modifiedDate; + $tempTodo = $todo; + break; + } + } + file_put_contents($this->filePath, json_encode($todos)); + return $tempTodo; + } + + public function deleteTodo($id) + { + $todos = json_decode(file_get_contents($this->filePath), true); + foreach ($todos as $key => $todo) { + if ($todo['id'] == $id) { + unset($todos[$key]); + break; + } + } + file_put_contents($this->filePath, json_encode(array_values($todos))); + } +} diff --git a/phptodo/src/todos.json b/phptodo/src/todos.json new file mode 100644 index 0000000..e69de29 diff --git a/phptodo/todos.json b/phptodo/todos.json new file mode 100644 index 0000000..a42e8d7 --- /dev/null +++ b/phptodo/todos.json @@ -0,0 +1 @@ +[{"id":4,"task":"task4","description":"","completed":false,"edited":false,"serialNumber":10,"lastViewed":false,"createdDate":"2023-10-06T10:41:11.806Z","modifiedDate":"2023-10-06T10:41:11.806Z"},{"id":3,"task":"task5","description":"","completed":false,"edited":false,"serialNumber":10,"lastViewed":false,"createdDate":"2023-10-06T10:41:11.806Z","modifiedDate":"2023-10-06T10:41:11.806Z"}] \ No newline at end of file