To participate you must create an account on apostrophenow.org. If you have already done so, click Login.

root/plugins/apostrophePlugin/trunk/lib/action/BaseaMediaBackendActions.class.php @ 1255

Revision 1255, 9.1 KB (checked in by tboutell, 3 years ago)

app_aMedia_jpeg_quality is now available to alter the default JPEG quality setting (75)

Line 
1<?php
2
3// Methods of this class serve static, permanent URLs that are not part of the
4// CMS address space. That would be the dynamic rendering of images that haven't
5// been cached yet, access to originals, and access to the REST API.
6
7class BaseaMediaBackendActions extends sfActions
8{
9  public function executeOriginal(sfRequest $request)
10  {
11    $item = $this->getItem();
12    $format = $request->getParameter('format');
13    $this->forward404Unless(
14      in_array($format, 
15      array_keys(aMediaItemTable::$mimeTypes)));
16    $path = $item->getOriginalPath($format);
17    if (!file_exists($path))
18    {
19      // Make an "original" in the other format (conversion but no scaling)
20      aImageConverter::convertFormat($item->getOriginalPath(),
21        $item->getOriginalPath($format));
22    }
23    header("Content-type: " . aMediaItemTable::$mimeTypes[$format]);
24    readfile($item->getOriginalPath($format));
25    // Don't let the binary get decorated with crap
26    exit(0);
27  }
28
29  public function executeImage(sfRequest $request)
30  {
31    $item = $this->getItem();
32    $slug = $item->getSlug();
33    $width = ceil($request->getParameter('width') + 0);
34    $height = ceil($request->getParameter('height') + 0);
35    $resizeType = $request->getParameter('resizeType');
36    $format = $request->getParameter('format');
37    $this->forward404Unless(
38      in_array($format, 
39      array_keys(aMediaItemTable::$mimeTypes)));
40    $this->forward404Unless(($resizeType !== 'c') || ($resizeType !== 's'));
41    $output = $this->getDirectory() . 
42      DIRECTORY_SEPARATOR . "$slug.$width.$height.$resizeType.$format";
43    // If .htaccess has not been set up, or we are not running
44    // from the default front controller, then we may get here
45    // even though the file already exists. Tolerate that situation
46    // with reasonable efficiency by just outputting it.
47   
48    if (!file_exists($output))
49    {
50      $originalFormat = $item->getFormat();
51      if ($resizeType === 'c')
52      {
53        $method = 'cropOriginal';
54      }
55      else
56      {
57        $method = 'scaleToFit';
58      }
59      $quality = sfConfig::get('app_aMedia_jpeg_quality', 75);
60      aImageConverter::$method(
61        aMediaItemTable::getDirectory() .
62          DIRECTORY_SEPARATOR .
63          "$slug.original.$originalFormat", 
64        $output,
65        $width,
66        $height,
67        sfConfig::get('app_aMedia_jpeg_quality', 75));
68    }
69    // The FIRST time, we output this here. Later it
70    // can come directly from the file if Apache is
71    // configured with our recommended directives and
72    // we're in the default controller. If we're in another
73    // controller, this is still pretty efficient because
74    // we don't generate the image again, but there is the
75    // PHP interpreter hit to consider, so use those directives!
76    header("Content-length: " . filesize($output));
77    header("Content-type: " . aMediaItemTable::$mimeTypes[$format]);
78    readfile($output);
79      // If I don't bail out manually here I get PHP warnings,
80    // even if I return sfView::NONE
81    exit(0);
82  }
83 
84  protected $validAPIKey = false;
85  // TODO: beef this up to challenge/response
86  protected $user = false;
87  protected function validateAPIKey()
88  {
89    // Media API is no longer used internally and defaults to off in apostrophePlugin
90    $this->forward404Unless(sfConfig::get('app_a_media_apienabled', false));
91    if (!$this->hasRequestParameter('apikey'))
92    {
93      if (!aMediaTools::getOption("apipublic"))
94      {
95        $this->logMessage('info', 'flunking because no apikey');
96        $this->unauthorized();
97      }
98      return;
99    }
100    $apikey = $this->getRequestParameter('apikey');
101    $apikeys = array_flip(aMediaTools::getOption('apikeys'));
102    if (!isset($apikeys[$apikey]))
103    {
104      $this->logMessage('info', 'ZZ flunking because bad apikey');     
105    }
106    $this->forward404Unless(isset($apikeys[$apikey]));
107    $this->validAPIKey = true;
108    $this->user = false;
109    if ($this->validAPIKey)
110    {
111      // With a valid API key you can request media info on behalf of any user
112      $this->user = $this->getRequestParameter('user');
113    }
114    if (!$this->user)
115    {
116      // Use of the API from javascript as an already authenticated user
117      // is permitted
118      if ($this->getUser()->isAuthenticated())
119      {
120        $guardUser = $this->getUser()->getGuardUser();
121        if ($guardUser)
122        {
123          $this->user = $guardUser->getUsername();
124        }
125      }
126    }
127  }
128 
129  protected function unauthorized()
130  {
131    header("HTTP/1.1 401 Unauthorization Required");
132    exit(0);
133  }
134 
135  public function executeTags(sfRequest $request)
136  {
137    $this->validateAPIKey();
138    $tags = PluginTagTable::getAllTagName(); 
139    $this->jsonResponse('ok', $tags);
140  }
141 
142  public function executeInfo(sfRequest $request)
143  {
144    $params = array();
145    $this->validateAPIKey();
146   
147    if ($request->hasParameter('ids'))
148    {
149                        $ids = $request->getParameter('ids');
150      if (!preg_match("/^(\d+\,?)*$/", $ids))
151      {
152        // Malformed request
153        $this->jsonResponse('malformed');
154      }
155      $ids = explode(",", $ids);
156      if ($ids === false)
157      {
158        $ids = array();
159      }
160      $params['ids'] = $ids;
161    }
162   
163    $numbers = array(
164      "width", "height", "minimum-width", "minimum-height", "aspect-width", "aspect-height"
165    );
166    foreach ($numbers as $number)
167    {
168      if ($request->hasParameter($number))
169      {
170        $n = $request->getParameter($number) + 0;
171        if ($number < 0)
172        {
173          $n = 0;
174        }
175        $params[$number] = $n;
176      }
177    }
178    $strings = array(
179      "tag", "search", "type", "user"
180    );
181    foreach ($strings as $string)
182    {
183      if ($request->hasParameter($string))
184      {
185        $params[$string] = $request->getParameter($string);
186      }
187    }   
188    if (isset($params['tag']))
189    {
190      $this->logMessage("ZZZZZ got tag: " . $params['tag'], "info");
191    }
192    $query = aMediaItemTable::getBrowseQuery($params);
193    $countQuery = clone $query;
194    $countQuery->offset(0);
195    $countQuery->limit(0);
196    $result = new StdClass();
197    $result->total = $countQuery->count();
198   
199    if ($request->hasParameter('offset'))
200    {
201      $offset = max($request->getParameter('offset') + 0, 0);
202      $query->offset($offset);
203    }
204    if ($request->hasParameter('limit'))
205    {
206      $limit = max($request->getParameter('limit') + 0, 0);
207      $query->limit($limit);
208    }
209    $absolute = !!$request->getParameter('absolute', false);
210    $items = $query->execute();
211    $nitems = array();
212    foreach ($items as $item)
213    {
214      $info = array();
215      $info['type'] = $item->getType();
216      $info['id'] = $item->getId();
217      $info['slug'] = $item->getSlug();
218      $info['width'] = $item->getWidth();
219      $info['height'] = $item->getHeight();
220      $info['format'] = $item->getFormat();
221      $info['title'] = $item->getTitle();
222      $info['description'] = $item->getDescription();
223      $info['credit'] = $item->getCredit();
224      $info['tags'] = array_keys($item->getTags());
225      // The embed HTML we suggest is a template in which they can
226      // replace _WIDTH_ and _HEIGHT_ and _c-OR-s_ with
227      // whatever they please
228     
229      // Absolute URL option
230      $info['embed'] = $item->getEmbedCode('_WIDTH_', '_HEIGHT_', '_c-OR-s_', '_FORMAT_', $absolute);
231      // The image URL we suggest is a template in which they can
232      // replace _WIDTH_, _HEIGHT_, _c-OR-s_ and _FORMAT_ with
233      // whatever they please
234      $controller = sfContext::getInstance()->getController();
235     
236      // Must use keys that will be acceptable as property names, no hyphens!
237     
238      // original refers to the original file, if we ever had it
239      // (images and PDFs). If you ask for the original of a video, you
240      // currently get the media plugin's copy of the best available still.
241     
242      $info['original'] = $controller->genUrl("@a_media_original?" .
243        http_build_query(
244          array(
245            "slug" => $item->getSlug(),
246            "format" => $item->getFormat()), $absolute));
247
248      $info['image'] = $controller->genUrl("a_media_image?" .
249        http_build_query(
250          array(
251            "slug" => $item->getSlug(),
252            "width" => "1000001", 
253            "height" => "1000002", 
254            "format" => "jpg", 
255            "resizeType" => "c")), 
256          $absolute);
257      $info['image'] = str_replace(array("1000001", "1000002", ".c."),
258        array("_WIDTH_", "_HEIGHT_", "._c-OR-s_."), $info['image']);
259      $info['image'] = preg_replace("/\.jpg$/", "._FORMAT_", $info['image']);
260      if ($info['type'] === 'video')
261      {
262        $info['serviceUrl'] = $item->getServiceUrl();
263      }
264      $nitems[] = $info;
265    }
266    $result->items = $nitems;
267    $this->jsonResponse('ok', $result);
268  }
269 
270  protected function getDirectory()
271  {
272    return aMediaItemTable::getDirectory();
273  }
274 
275  protected function getItem()
276  {
277    return aMediaTools::getItem($this);
278  }
279 
280  static protected function jsonResponse($status, $result)
281  {
282    header("Content-type: text/plain");
283    echo(json_encode(array("status" => $status, "result" => $result)));
284    // Don't let debug controllers etc decorate it with crap
285    exit(0);
286  }
287}
Note: See TracBrowser for help on using the browser.