Dropbox帐户作为Wordpress上传文件夹

时间:2016-12-03 16:54:25

标签: php wordpress dropbox

由于我正在开发一个可能存有大量图片的网站,我想知道我是否可以将标准的WordPress上传文件夹设置为Dropbox帐户?

如果是这样,我该怎么做?

如果我能够在一个maner中实现它,那就好了,即使WordPress也不知道它是一个遥远的'夹。媒体上传应该与原生WordPress设置中的工作方式相同。

我已经了解了使用其他文件夹代替wp-content/uploads的可能性,但我找不到有关使用Dropbox的任何信息。

2 个答案:

答案 0 :(得分:3)

是的,你可以做到。只要您在Dropbox 上保留相同的结构并将Dropbox可共享链接保存为原始文件和生成的大小的元数据,一个简单但完全正常的设置将类似于以下内容,将thephpleague/flysystemDropbox Adapter

一起使用

第1步

使用以下内容将名为composer.json的文件添加到主题的根目录:

{
  "require": {
    "league/flysystem": "^1",
    "league/flysystem-dropbox": "^1"
  }
}

第2步

following these instructions

安装Composer

第3步

使用终端/控制台上的命令行,转到主题目录并运行:

composer install -o

第4步

创建Dropbox App here。 我建议你选择“App folder”作为访问类型。 将在您的Dropbox帐户根目录的“Apps”目录中创建与您的应用名称匹配的目录;这将是Dropbox上的“上传”目录。

第5步

转到您的应用管理页面并生成新的访问令牌。 将访问令牌保存在某处并复制“App secret”

第6步

将以下内容添加到functions.php

use League\Flysystem\AdapterInterface;
use League\Flysystem\Adapter\Local as LocalAdapter;
use League\Flysystem\Dropbox\DropboxAdapter;
use League\Flysystem\Filesystem;
use League\Flysystem\MountManager;
use Dropbox\Client as DropboxClient;

// Autoload vendors
require_once __DIR__ .'/vendor/autoload.php';

/**
 * Class that will handle uploading to Dropbox
 * 
 */
class SO40950172Filesystem {

  /**
   * Contains several mounted filesystems
   * 
   * @var League\Flysystem\MountManager object
   */
  protected $filesystem;

  /**
   * Contains Dropbox client
   *
   * We need this accessible to create shareable links
   * 
   * @var Dropbox\Client object
   */
  protected $dropbox_client;

  /**
   * Instantiates this class
   */
  public function __construct() {

    // Get WordPress uploads directory info
    $uploads_info = wp_upload_dir();

    // Create Local filesystem
    $local_adapter = new LocalAdapter($uploads_info['basedir']);
    $local_fs      = new Filesystem($local_adapter, [
        'visibility' => AdapterInterface::VISIBILITY_PUBLIC
    ]);

    // Create Dropbox filesystem
    $this->dropbox_client  = new DropboxClient($app_access_token, $app_secret);
    $dropbox_adapter = new DropboxAdapter($this->dropbox_client, '/');
    $dropbox_fs      = new Filesystem($dropbox_adapter, [
      'visibility' => AdapterInterface::VISIBILITY_PUBLIC
    ]);

    // Set filesystem manager
    $this->filesystem = new MountManager([
      'local'   => $local_fs,
      'dropbox' => $dropbox_fs
    ]);
  }

  /**
   * Uploads file to Dropbox
   * 
   * @param  string $path Path to file
   * @return object       Current object
   */
  public function uploadToDropbox($path)
  {
    // Normalize path
    $path = static::getNormalizedPath($path);

    // Get content from the local file
    $content = $this->read("local://$path");

    // Push file to Dropbox
    $this->put("dropbox://$path", $content);

    return $this;
  }

  /**
   * Deletes file from Dropbox
   * 
   * @param  string $path Path to file
   * @return object       Current object
   */
  public function deleteFromDropbox($path)
  {
    // Normalize path
    $path = static::getNormalizedPath($path);

    // Delete file from Dropbox
    $this->delete("dropbox://$path");

    return $this;
  }

  /**
   * Returns the unique identifier path section of a Dropbox URL
   * 
   * @param  string $path Path to file
   * @return string       Dropbox URL unique identifier
   */
  public function getDropboxUrlID($path)
  {
    // Normalize path
    $path = static::getNormalizedPath($path);

    // Get unique link
    $url = $this->dropbox_client->createShareableLink("/$path");

    // Parse URL to retrive its path
    $url_info = parse_url($url);
    $url_path = $url_info['path'];

    // Remove "s/" section and file name from the URL path
    $id = str_replace(['s/', basename($path)], '', $url_path);

    // Return Dropbox unique identifier for this file URL
    return trim($id, '/');
  }

  /**
   * Returns clean & relative paths
   * 
   * @param  string $path Raw path
   * @return string       Parsed path
   */
  public static function getNormalizedPath($path)
  {
    // Get WordPress uploads directory info
    $uploads_info = wp_upload_dir();

    // Remove uploads base path so that we end up
    // with the "/YYYY/MM/filename.extension" format
    $path = str_replace($uploads_info['basedir'], '', $path);

    // Remove uploads base url so that we end up
    // with the "/YYYY/MM/filename.extension" format
    $path = str_replace($uploads_info['baseurl'], '', $path);

    // Remove forward slashes on both ends
    $path = trim($path, '/');

    // Return path
    return $path;
  }

  /**
   * Making sure all calls go to $this->filesystem
   * 
   * @param  string $name Method name
   * @param  array  $args Method arguments
   * @return mixed        
   */
  public function __call($name, array $args)
  {
    if (method_exists($this->filesystem, $name))
      throw new \Exception("\League\Flysystem\MountManager doesn't have \"$name\" method");

    return call_user_func_array([$this->filesystem, $name], $args);
  }
}

// Manipulate media URLs sitewide
add_filter('wp_get_attachment_url', 'so_40950172_get_dropbox_url', 9, 2);

function so_40950172_get_dropbox_url($absolute_url, $post_id) {

  // Get normalized path
  $path = SO40950172Filesystem::getNormalizedPath($absolute_url);

  // Get only the filename
  $path = basename($path);

  // Get Dropbox URL unique ID
  $id = get_post_meta($post_id, 'dropbox_id_'. $path, true);

  // Return absolute URL
  return $id ? "https://dl.dropboxusercontent.com/s/$id/$path/?dl=0" : $path;
}

// Upload new and updated files to Dropbox
add_filter('wp_update_attachment_metadata', 'so_40950172_upload_to_dropbox', 9, 2);

function so_40950172_upload_to_dropbox($data, $post_id) {

  // Get filesystem
  $fs = new SO40950172Filesystem();

  // Upload original file to Dropbox
  $fs->uploadToDropbox($data['file']);

  // Add Dropbox URL unique ID to meta data
  add_post_meta($post_id, 'dropbox_id_'. basename($data['file']), $fs->getDropboxUrlID($data['file']));

  // Upload intermediate image sizes
  if (isset($data['sizes']) && $data['sizes']) {

    // Get year and month prefix (e.g /YYYY/MM) from original file
    $base_path = dirname($data['file']);

    // Loop through all sizes
    foreach ($data['sizes'] as $size_name => $size_data) {

      // Set path for current size
      $size_path = $base_path .'/'. $size_data['file'];

      // Upload size to Dropbox
      $fs->uploadToDropbox($size_path);

      // Add Dropbox URL unique ID to meta data
      add_post_meta($post_id, 'dropbox_id_'. basename($size_path), $fs->getDropboxUrlID($size_path));
    }
  }

  return $data;
}

// Delete Dropbox file
add_filter('wp_delete_file', 'so_40950172_delete_dropbox_file');

function so_40950172_delete_dropbox_file($absolute_path) {

  // Get filesystem
  $fs = new SO40950172Filesystem();

  // Delete file from Dropbox
  $fs->deleteFromDropbox($absolute_path);
}

第7步

关于您刚刚粘贴到functions.php的代码:

  • $app_access_token替换为您生成的Dropbox应用访问令牌
  • $app_secret替换为Dropbox app secret

备注

原始文件和生成的尺寸也将保存在本地,但您无需担心它们。如果您想要和/或关心磁盘空间,您甚至可以在确认上传成功后删除本地文件。

我还测试了内置的图像编辑器,它没有任何问题。

如果您需要在Dropbox端移动东西并且由于数据库上没有保存信息(这很好),您只需要更新上面的功能。
显然你可以镜像Dropbox上的WordPress结构,但你不能简单地使用基本URL和WordPress上传结构链接到它们来获取URL,你真的需要为每个原始文件获取shareable link并生成大小和存储关于它们的东西作为元数据。在上面的代码中,我选择只将URL的唯一部分存储为元数据,这实际上是关于它们的唯一独特之处。

我知道这是偏离主题的,但我建议使用AWS S3或Google Cloud Storage,因为您可以使用与Dropbox完全相同的文件结构访问您的文件。无需将任何内容保存为元数据。

答案 1 :(得分:0)

这是一个有趣的想法,但WordPress使用数据库关系来管理上传的图像 - 所以我认为你必须通过媒体上传器处理图像。 TL:DR; - 你不能。