Browse Source

Level 2.2: using urlRoot, saving.

Frederic G. MARAND 6 years ago
parent
commit
e9923bfa95

+ 3 - 1
.idea/CodeSchool Backbone 1.iml

@@ -1,7 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <module type="WEB_MODULE" version="4">
   <component name="NewModuleRootManager">
-    <content url="file://$MODULE_DIR$" />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+    </content>
     <orderEntry type="inheritedJdk" />
     <orderEntry type="sourceFolder" forTests="false" />
     <orderEntry type="module-library">

+ 27 - 0
.idea/php.xml

@@ -1,4 +1,31 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
+  <component name="PhpIncludePathManager">
+    <include_path>
+      <path value="$PROJECT_DIR$/vendor/symfony/twig-bridge" />
+      <path value="$PROJECT_DIR$/vendor/symfony/polyfill-php70" />
+      <path value="$PROJECT_DIR$/vendor/silex/silex" />
+      <path value="$PROJECT_DIR$/vendor/symfony/http-kernel" />
+      <path value="$PROJECT_DIR$/vendor/silex/web-profiler" />
+      <path value="$PROJECT_DIR$/vendor/symfony/polyfill-php72" />
+      <path value="$PROJECT_DIR$/vendor/symfony/asset" />
+      <path value="$PROJECT_DIR$/vendor/symfony/polyfill-mbstring" />
+      <path value="$PROJECT_DIR$/vendor/symfony/event-dispatcher" />
+      <path value="$PROJECT_DIR$/vendor/symfony/routing" />
+      <path value="$PROJECT_DIR$/vendor/composer" />
+      <path value="$PROJECT_DIR$/vendor/psr/log" />
+      <path value="$PROJECT_DIR$/vendor/symfony/var-dumper" />
+      <path value="$PROJECT_DIR$/vendor/psr/container" />
+      <path value="$PROJECT_DIR$/vendor/symfony/debug" />
+      <path value="$PROJECT_DIR$/vendor/symfony/web-profiler-bundle" />
+      <path value="$PROJECT_DIR$/vendor/pimple/pimple" />
+      <path value="$PROJECT_DIR$/vendor/twig/twig" />
+      <path value="$PROJECT_DIR$/vendor/monolog/monolog" />
+      <path value="$PROJECT_DIR$/vendor/symfony/stopwatch" />
+      <path value="$PROJECT_DIR$/vendor/symfony/http-foundation" />
+      <path value="$PROJECT_DIR$/vendor/symfony/monolog-bridge" />
+      <path value="$PROJECT_DIR$/vendor/paragonie/random_compat" />
+    </include_path>
+  </component>
   <component name="PhpProjectSharedConfiguration" php_language_level="7" />
 </project>

+ 7 - 0
.idea/symfony2.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Symfony2PluginSettings">
+    <option name="pathToTranslation" value="var/cache/dev/translations" />
+    <option name="pluginEnabled" value="true" />
+  </component>
+</project>

+ 2 - 0
config/prod.php

@@ -6,3 +6,5 @@ $app['twig.path'] = [__DIR__ . '/../templates'];
 $app['twig.options'] = ['cache' => __DIR__ . '/../var/cache/twig'];
 
 $app['app.mail_to'] = 'support@osinet.fr';
+
+$app['data'] = __DIR__ . '/../web/data/items.json';

+ 35 - 0
src/Model.php

@@ -0,0 +1,35 @@
+<?php
+
+use Symfony\Component\HttpFoundation\Response;
+
+class Model {
+  protected $data;
+  protected $path;
+
+  public function __construct(string $path) {
+    $this->path = $path;
+  }
+
+  public function load() {
+    $raw = file_get_contents($this->path);
+    $this->data = json_decode($raw, true);
+    return $this->data;
+  }
+
+  public function save(array $doc) {
+    if (empty($doc['id'])) {
+      $id = (int) max(array_keys($this->data)) + 1;
+      $doc['id'] = $id;
+      $created = true;
+    }
+    else {
+      $id = (int) $doc['id'];
+      $created = false;
+    }
+
+    $this->data[$id] = $doc;
+    $raw = json_encode($this->data);
+    file_put_contents($this->path, $raw);
+    return $created;
+  }
+}

+ 2 - 0
src/boot.php

@@ -22,4 +22,6 @@ $app['twig'] = $app->extend('twig', function ($twig, $app) {
 // Support PATCH/PUT/DELETE.. emulation on POST for browsers. Beware XSS.
 Request::enableHttpMethodParameterOverride();
 
+$app['model'] = function (Application $app) { return new Model($app['data']); };
+
 return $app;

+ 19 - 0
src/controllers.php

@@ -1,6 +1,8 @@
 <?php
 
 use Silex\Application;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
 
 const BACKBONE = '/client/index.html';
 
@@ -10,3 +12,20 @@ $app->get('/', function (Application $app) {
 $app->get('/server', function (Application $app) {
   return $app->redirect(BACKBONE);
 });
+$app->get('/todos/{id}', function (Application $app, int $id) {
+  /** @var \Model $model */
+  $model = $app['model'];
+  $todos = $model->load();
+  $todo = $todos[$id] ?? NULL;
+  return $app->json($todo);
+});
+$app->put('/todos/{id}', function (Application $app, Request $request, int $id) {
+  /** @var \Model $model */
+  $model = $app['model'];
+  $data = json_decode($request->getContent(), true);
+  $created = $model->save($data);
+  return new Response('Saved', $created ? Response::HTTP_CREATED : Response::HTTP_OK);
+});
+$app->match('{url}', function ($url) {
+  var_dump($url);
+});

+ 10 - 10
web/client/lib/todos.js

@@ -1,21 +1,21 @@
 $(function () {
   // Create a model class.
-  const TodoItem = Backbone.Model.extend({});
-  // Create a model instance.
-  const todoItem = new TodoItem({
-    description: "Remember the milk",
-    status: "incomplete",
-    id: 1
+  const TodoItem = Backbone.Model.extend({
+    // RESTful web service, RoR flavor.
+    urlRoot: '/server/todos'
   });
+  // Create a model instance to load it by ID.
+  const todoItem = new TodoItem({ id: 1 });
+
+  // Access the server at /server/todos/1 (urlRoot + '/' + item.id).
+  const x = todoItem.fetch({ async: false });
 
   // Manipulate attributes.
   const description = todoItem.get('description');
   todoItem.set('status', 'complete');
 
-  // Access the server: needs some configuration.
-  todoItem.url = '/server/todo';
-  const x = todoItem.fetch({ async: false });
-  // todoItem.save();
+  // Save on server.
+  todoItem.save();
 
   // Create a view class.
   const TodoView = Backbone.View.extend({

+ 10 - 10
web/client/src/todos.js

@@ -1,21 +1,21 @@
 $(function () {
   // Create a model class.
-  const TodoItem = Backbone.Model.extend({});
-  // Create a model instance.
-  const todoItem = new TodoItem({
-    description: "Remember the milk",
-    status: "incomplete",
-    id: 1,
+  const TodoItem = Backbone.Model.extend({
+    // RESTful web service, RoR flavor.
+    urlRoot: '/server/todos',
   });
+  // Create a model instance to load it by ID.
+  const todoItem = new TodoItem({ id: 1 });
+
+  // Access the server at /server/todos/1 (urlRoot + '/' + item.id).
+  const x = todoItem.fetch({ async: false });
 
   // Manipulate attributes.
   const description = todoItem.get('description');
   todoItem.set('status', 'complete');
 
-  // Access the server: needs some configuration.
-  todoItem.url = '/server/todo';
-  const x = todoItem.fetch({ async: false });
-  // todoItem.save();
+  // Save on server.
+  todoItem.save();
 
   // Create a view class.
   const TodoView = Backbone.View.extend({

+ 0 - 0
web/data/item.json


+ 1 - 0
web/data/items.json

@@ -0,0 +1 @@
+{"1":{"id":1,"description":"Pick up milk","status":"incomplete"}}