Add files via upload

pull/4/head
qkqpttgf 2020-01-18 20:12:21 +08:00 committed by GitHub
parent 2d18cc8167
commit 4f9ad01eb4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
48 changed files with 9641 additions and 93 deletions

7
app.json Normal file
View File

@ -0,0 +1,7 @@
{
"name": "herokuOnedrive",
"description": "Deploy herokuOnedrive to heroku",
"website": "https://github.com/qkqpttgf/herokuOnedrive",
"repository": "https://github.com/qkqpttgf/herokuOnedrive",
"success_url": "/"
}

4
config.php Normal file
View File

@ -0,0 +1,4 @@
<?php $configs = '
{
}
';

View File

@ -1,5 +1,4 @@
<?php <?php
global $exts; global $exts;
global $constStr; global $constStr;
@ -14,343 +13,397 @@ $constStr = [
'languages' => [ 'languages' => [
'en-us' => 'English', 'en-us' => 'English',
'zh-cn' => '中文', 'zh-cn' => '中文',
'ja' => '日本語',
], ],
'Week' => [ 'Week' => [
0 => [ 'en-us' => [
'en-us' => 'Sunday', 0 => 'Sunday',
'zh-cn' => '星期日', 1 => 'Monday',
2 => 'Tuesday',
3 => 'Wednesday',
4 => 'Thursday',
5 => 'Friday',
6 => 'Saturday',
], ],
1 => [ 'zh-cn' => [
'en-us' => 'Monday', 0 => '星期日',
'zh-cn' => '星期一', 1 => '星期一',
2 => '星期二',
3 => '星期三',
4 => '星期四',
5 => '星期五',
6 => '星期六',
], ],
2 => [ 'ja' => [
'en-us' => 'Tuesday', 0 => '日曜日',
'zh-cn' => '星期二', 1 => '月曜日',
], 2 => '火曜日',
3 => [ 3 => '水曜日',
'en-us' => 'Wednesday', 4 => '木曜日',
'zh-cn' => '星期三', 5 => '金曜日',
], 6 => '土曜日',
4 => [
'en-us' => 'Thursday',
'zh-cn' => '星期四',
],
5 => [
'en-us' => 'Friday',
'zh-cn' => '星期五',
],
6 => [
'en-us' => 'Saturday',
'zh-cn' => '星期六',
], ],
], ],
'EnvironmentsDescription' => [ 'EnvironmentsDescription' => [
'admin' => [ 'en-us' => [
'en-us' => 'The admin password, Login button will not show when empty', 'admin' => 'The admin password, Login button will not show when empty',
'zh-cn' => '管理密码,不添加时不显示登录页面且无法登录。', 'adminloginpage' => 'if set, the Login button will not display, and the login page no longer \'?admin\', it is \'?{this value}\'.',
'domain_path' => 'more custom domain, format is a1.com:/dirto/path1|b2.com:/path2',
'guestup_path' => 'Set guest upload dir, before set this, the files in this dir will show as normal.',
'passfile' => 'The password of dir will save in this file.',
'public_path' => 'Show this Onedrive dir when through the long url of API Gateway; public show files less than private.',
'sitename' => 'sitename',
'Onedrive_ver' => 'Onedrive version',
], ],
'adminloginpage' => [ 'zh-cn' => [
'en-us' => 'if set, the Login button will not display, and the login page no longer \'?admin\', it is \'?{this value}\'.', 'admin' => '管理密码,不添加时不显示登录页面且无法登录。',
'zh-cn' => '如果设置,登录按钮及页面隐藏。管理登录的页面不再是\'?admin\',而是\'?此设置的值\'。', 'adminloginpage' => '如果设置,登录按钮及页面隐藏。管理登录的页面不再是\'?admin\',而是\'?此设置的值\'。',
'domain_path' => '使用多个自定义域名时指定每个域名看到的目录。格式为a1.com:/dirto/path1|b1.com:/path2比private_path优先。',
'guestup_path' => '设置游客上传路径(图床路径),不设置这个值时该目录内容会正常列文件出来,设置后只有上传界面,不显示其中文件(登录后显示)。',
'passfile' => '自定义密码文件的名字,可以是\'pppppp\',也可以是\'aaaa.txt\'等等;列目录时不会显示,只有知道密码才能查看或下载此文件。密码是这个文件的内容,可以空格、可以中文;',
'public_path' => '使用API长链接访问时显示网盘文件的路径不设置时默认为根目录不能是private_path的上级public看到的不能比private多要么看到的就不一样。',
'sitename' => '网站的名称',
'Onedrive_ver' => 'Onedrive版本',
], ],
'domain_path' => [ 'ja' => [
'en-us' => 'more custom domain, format is a1.com:/dirto/path1|b2.com:/path2', 'admin' => 'パスワードを管理する、追加しない場合、ログインページは表示されず、ログインできません。',
'zh-cn' => '使用多个自定义域名时指定每个域名看到的目录。格式为a1.com:/dirto/path1|b1.com:/path2比private_path优先。', 'adminloginpage' => '設定すると、ログインボタンとページが非表示になります。ログインを管理するためのページは\'?admin \'ではなく、\'?この設定の値\'。',
], 'domain_path' => '複数のカスタムドメイン名を使用する場合、各ドメイン名に表示されるディレクトリを指定します。形式はa1.com:/dirto/path1|b1.com:/path2で、private_pathよりも優先されます。',
'imgup_path' => [ 'guestup_path' => 'マップベッドのパスを設定します。この値が設定されていない場合、ディレクトリの内容は通常ファイルにリストされ、設定後はアップロードインターフェイスのみが表示されます。',
'en-us' => 'Set guest upload dir, before set this, the files in this dir will show as normal.', 'passfile' => 'カスタムパスワードファイルの名前は、\'pppppp \'、\'aaaa.txt \'などの場合があります。ディレクトリをリストするときには表示されません。パスワードを知っている場合にのみ、このファイルを表示またはダウンロードできます。 パスワードはこのファイルの内容であり、スペースまたは漢字を使用できます。',
'zh-cn' => '设置图床路径,不设置这个值时该目录内容会正常列文件出来,设置后只有上传界面,不显示其中文件(登录后显示)。', 'public_path' => 'APIのロングリンクアクセスを使用する場合、ネットワークディスクファイルのパスが表示されますが、設定されていない場合はデフォルトでルートディレクトリになり、private_pathの上位にはなりませんpublicはprivate以上のものを見ることができません。それ以外は異なります。。',
], 'sitename' => 'ウェブサイト名',
'passfile' => [ 'Onedrive_ver' => 'Onedriveバージョン',
'en-us' => 'The password of dir will save in this file.',
'zh-cn' => '自定义密码文件的名字,可以是\'pppppp\',也可以是\'aaaa.txt\'等等;列目录时不会显示,只有知道密码才能查看或下载此文件。密码是这个文件的内容,可以空格、可以中文;',
],
'private_path' => [
'en-us' => 'Show this Onedrive dir when through custom domain, default is \'/\'.',
'zh-cn' => '使用自定义域名访问时,显示网盘文件的路径,不设置时默认为根目录。',
],
'public_path' => [
'en-us' => 'Show this Onedrive dir when through the long url of API Gateway; public show files less than private.',
'zh-cn' => '使用API长链接访问时显示网盘文件的路径不设置时默认为根目录不能是private_path的上级public看到的不能比private多要么看到的就不一样。',
],
'sitename' => [
'en-us' => 'sitename',
'zh-cn' => '网站的名称',
],
'language' => [
'en-us' => 'en-us or zh-cn',
'zh-cn' => '目前en-us 或 zh-cn',
],
'APIKey' => [
'en-us' => 'the APIKey of Heroku',
'zh-cn' => 'Heroku的API Key',
],
'Onedrive_ver' => [
'en-us' => 'Onedrive version',
'zh-cn' => 'Onedrive版本',
], ],
], ],
'SetSecretsFirst' => [ 'SetSecretsFirst' => [
'en-us' => 'Set APIKey in Config vars first! Then reflesh.', 'en-us' => 'Set APIKey in Config vars first! Then reflesh.',
'zh-cn' => '先在环境变量设置APIKey再刷新。', 'zh-cn' => '先在环境变量设置APIKey再刷新。',
'ja' => '最初に環境変数にAPIKeyを設定してください 再度更新します。',
], ],
'RefleshtoLogin' => [ 'RefleshtoLogin' => [
'en-us' => '<font color="red">Reflesh</font> and login.', 'en-us' => '<font color="red">Reflesh</font> and login.',
'zh-cn' => '请<font color="red">刷新</font>页面后重新登录', 'zh-cn' => '请<font color="red">刷新</font>页面后重新登录',
'ja' => 'ページを<font color = "red">更新</font>して、再度ログインしてください',
], ],
'AdminLogin' => [ 'AdminLogin' => [
'en-us' => 'Admin Login', 'en-us' => 'Admin Login',
'zh-cn' => '管理登录', 'zh-cn' => '管理登录',
'ja' => 'ログインを管理する',
], ],
'LoginSuccess' => [ 'LoginSuccess' => [
'en-us' => 'Login Success!', 'en-us' => 'Login Success!',
'zh-cn' => '登录成功,正在跳转', 'zh-cn' => '登录成功,正在跳转',
'ja' => 'ログイン成功、ジャンプ',
], ],
'InputPassword' => [ 'InputPassword' => [
'en-us' => 'Input Password', 'en-us' => 'Input Password',
'zh-cn' => '输入密码', 'zh-cn' => '输入密码',
'ja' => 'パスワードを入力してください',
], ],
'Login' => [ 'Login' => [
'en-us' => 'Login', 'en-us' => 'Login',
'zh-cn' => '登录', 'zh-cn' => '登录',
'ja' => 'サインイン',
], ],
'encrypt' => [ 'encrypt' => [
'en-us' => 'Encrypt', 'en-us' => 'Encrypt',
'zh-cn' => '加密', 'zh-cn' => '加密',
'ja' => '暗号化',
], ],
'SetpassfileBfEncrypt' => [ 'SetpassfileBfEncrypt' => [
'en-us' => 'Set \'passfile\' in Environments before encrypt', 'en-us' => 'Set \'passfile\' in Environments before encrypt',
'zh-cn' => '先在环境变量设置passfile才能加密', 'zh-cn' => '先在环境变量设置passfile才能加密',
'ja' => '最初に暗号化する環境変数にパスファイルを設定します',
], ],
'updateProgram' => [ 'updateProgram' => [
'en-us' => 'Update Program', 'en-us' => 'Update Program',
'zh-cn' => '一键更新', 'zh-cn' => '一键更新',
'ja' => 'ワンクリック更新',
], ],
'UpdateSuccess' => [ 'UpdateSuccess' => [
'en-us' => 'Program update Success!', 'en-us' => 'Program update Success!',
'zh-cn' => '程序升级成功!', 'zh-cn' => '程序升级成功!',
'ja' => 'プログラムのアップグレードに成功しました!',
], ],
'Setup' => [ 'Setup' => [
'en-us' => 'Setup', 'en-us' => 'Setup',
'zh-cn' => '设置', 'zh-cn' => '设置',
'ja' => '設定する',
], ],
'Back' => [ 'Back' => [
'en-us' => 'Back', 'en-us' => 'Back',
'zh-cn' => '返回', 'zh-cn' => '返回',
'ja' => 'back',
], ],
'NotNeedUpdate' => [ 'NotNeedUpdate' => [
'en-us' => 'Not Need Update', 'en-us' => 'Not Need Update',
'zh-cn' => '不需要更新', 'zh-cn' => '不需要更新',
'ja' => '更新不要',
], ],
'Home' => [ 'Home' => [
'en-us' => 'Home', 'en-us' => 'Home',
'zh-cn' => '首页', 'zh-cn' => '首页',
'ja' => 'ホーム',
], ],
'NeedUpdate' => [ 'NeedUpdate' => [
'en-us' => 'Program can update<br>Click setup in Operate at top.', 'en-us' => 'Program can update<br>Click setup in Operate at top.',
'zh-cn' => '可以升级程序<br>在上方管理菜单中<br>进入设置页面升级', 'zh-cn' => '可以升级程序<br>在上方管理菜单中<br>进入设置页面升级',
'ja' => 'プログラムをアップグレードできます<br>上記の管理メニューで<br>アップグレードする設定ページに入ります',
], ],
'Operate' => [ 'Operate' => [
'en-us' => 'Operate', 'en-us' => 'Operate',
'zh-cn' => '管理', 'zh-cn' => '管理',
'ja' => '管理',
], ],
'Logout' => [ 'Logout' => [
'en-us' => 'Logout', 'en-us' => 'Logout',
'zh-cn' => '登出', 'zh-cn' => '登出',
'ja' => 'ログアウトする',
], ],
'Create' => [ 'Create' => [
'en-us' => 'Create', 'en-us' => 'Create',
'zh-cn' => '新建', 'zh-cn' => '新建',
'ja' => '新しい',
], ],
'Download' => [ 'Download' => [
'en-us' => 'download', 'en-us' => 'download',
'zh-cn' => '下载', 'zh-cn' => '下载',
'ja' => 'ダウンロードする',
], ],
'ClicktoEdit' => [ 'ClicktoEdit' => [
'en-us' => 'Click to edit', 'en-us' => 'Click to edit',
'zh-cn' => '点击后编辑', 'zh-cn' => '点击后编辑',
'ja' => 'クリック後に編集',
], ],
'Save' => [ 'Save' => [
'en-us' => 'Save', 'en-us' => 'Save',
'zh-cn' => '保存', 'zh-cn' => '保存',
'ja' => '保存する',
], ],
'FileNotSupport' => [ 'FileNotSupport' => [
'en-us' => 'File not support preview.', 'en-us' => 'File not support preview.',
'zh-cn' => '文件格式不支持预览', 'zh-cn' => '文件格式不支持预览',
'ja' => 'ファイル形式はプレビューをサポートしていません',
], ],
'File' => [ 'File' => [
'en-us' => 'File', 'en-us' => 'File',
'zh-cn' => '文件', 'zh-cn' => '文件',
'ja' => 'ファイル',
], ],
'ShowThumbnails' => [ 'ShowThumbnails' => [
'en-us' => 'Thumbnails', 'en-us' => 'Thumbnails',
'zh-cn' => '图片缩略', 'zh-cn' => '图片缩略',
'ja' => '画像のサムネイル',
], ],
'EditTime' => [ 'EditTime' => [
'en-us' => 'EditTime', 'en-us' => 'EditTime',
'zh-cn' => '修改时间', 'zh-cn' => '修改时间',
'ja' => '変更時間',
], ],
'Size' => [ 'Size' => [
'en-us' => 'Size', 'en-us' => 'Size',
'zh-cn' => '大小', 'zh-cn' => '大小',
'ja' => 'サイズ ',
], ],
'Rename' => [ 'Rename' => [
'en-us' => 'Rename', 'en-us' => 'Rename',
'zh-cn' => '重命名', 'zh-cn' => '重命名',
'ja' => '名前を変更',
], ],
'Move' => [ 'Move' => [
'en-us' => 'Move', 'en-us' => 'Move',
'zh-cn' => '移动', 'zh-cn' => '移动',
'ja' => '移動する',
], ],
'Delete' => [ 'Delete' => [
'en-us' => 'Delete', 'en-us' => 'Delete',
'zh-cn' => '删除', 'zh-cn' => '删除',
'ja' => '削除する',
], ],
'PrePage' => [ 'PrePage' => [
'en-us' => 'PrePage', 'en-us' => 'PrePage',
'zh-cn' => '上一页', 'zh-cn' => '上一页',
'ja' => '前へ',
], ],
'NextPage' => [ 'NextPage' => [
'en-us' => 'NextPage', 'en-us' => 'NextPage',
'zh-cn' => '下一页', 'zh-cn' => '下一页',
'ja' => '次のページ',
], ],
'Upload' => [ 'Upload' => [
'en-us' => 'Upload', 'en-us' => 'Upload',
'zh-cn' => '上传', 'zh-cn' => '上传',
'ja' => 'アップロードする',
], ],
'Submit' => [ 'Submit' => [
'en-us' => 'Submit', 'en-us' => 'Submit',
'zh-cn' => '确认', 'zh-cn' => '确认',
'ja' => '確認する',
], ],
'Close' => [ 'Close' => [
'en-us' => 'Close', 'en-us' => 'Close',
'zh-cn' => '关闭', 'zh-cn' => '关闭',
'ja' => '閉じる',
], ],
'InputPasswordUWant' => [ 'InputPasswordUWant' => [
'en-us' => 'Input Password you Want', 'en-us' => 'Input Password you Want',
'zh-cn' => '输入想要设置的密码', 'zh-cn' => '输入想要设置的密码',
'ja' => '設定するパスワードを入力してください',
], ],
'ParentDir' => [ 'ParentDir' => [
'en-us' => 'Parent Dir', 'en-us' => 'Parent Dir',
'zh-cn' => '上一级目录', 'zh-cn' => '上一级目录',
'ja' => '親ディレクトリ',
], ],
'Folder' => [ 'Folder' => [
'en-us' => 'Folder', 'en-us' => 'Folder',
'zh-cn' => '文件夹', 'zh-cn' => '文件夹',
'ja' => 'フォルダー',
], ],
'Name' => [ 'Name' => [
'en-us' => 'Name', 'en-us' => 'Name',
'zh-cn' => '名称', 'zh-cn' => '名称',
'ja' => '名前',
], ],
'Content' => [ 'Content' => [
'en-us' => 'Content', 'en-us' => 'Content',
'zh-cn' => '内容', 'zh-cn' => '内容',
'ja' => '内容',
], ],
'CancelEdit' => [ 'CancelEdit' => [
'en-us' => 'Cancel Edit', 'en-us' => 'Cancel Edit',
'zh-cn' => '取消编辑', 'zh-cn' => '取消编辑',
'ja' => '編集をキャンセル',
], ],
'GetFileNameFail' => [ 'GetFileNameFail' => [
'en-us' => 'Fail to Get File Name!', 'en-us' => 'Fail to Get File Name!',
'zh-cn' => '获取文件名失败!', 'zh-cn' => '获取文件名失败!',
'ja' => 'ファイル名を取得できませんでした!',
], ],
'GetUploadLink' => [ 'GetUploadLink' => [
'en-us' => 'Get Upload Link', 'en-us' => 'Get Upload Link',
'zh-cn' => '获取上传链接', 'zh-cn' => '获取上传链接',
'ja' => 'アップロードリンクを取得',
], ],
'UpFileTooLarge' => [ 'UpFileTooLarge' => [
'en-us' => 'The File is too Large!', 'en-us' => 'The File is too Large!',
'zh-cn' => '文件过大,终止上传。', 'zh-cn' => '文件过大,终止上传。',
'ja' => '超えると、アップロードは終了します。',
], ],
'UploadStart' => [ 'UploadStart' => [
'en-us' => 'Upload Start', 'en-us' => 'Upload Start',
'zh-cn' => '开始上传', 'zh-cn' => '开始上传',
'ja' => 'アップロードを開始',
], ],
'UploadStartAt' => [ 'UploadStartAt' => [
'en-us' => 'Start At', 'en-us' => 'Start At',
'zh-cn' => '开始于', 'zh-cn' => '开始于',
'ja' => 'で開始',
], ],
'ThisTime' => [ 'ThisTime' => [
'en-us' => 'This Time', 'en-us' => 'This Time',
'zh-cn' => '本次', 'zh-cn' => '本次',
'ja' => '今回は',
], ],
'LastUpload' => [ 'LastUpload' => [
'en-us' => 'Last time Upload', 'en-us' => 'Last time Upload',
'zh-cn' => '上次上传', 'zh-cn' => '上次上传',
'ja' => '上回は',
], ],
'AverageSpeed' => [ 'AverageSpeed' => [
'en-us' => 'AverageSpeed', 'en-us' => 'AverageSpeed',
'zh-cn' => '平均速度', 'zh-cn' => '平均速度',
'ja' => '平均速度',
], ],
'CurrentSpeed' => [ 'CurrentSpeed' => [
'en-us' => 'CurrentSpeed', 'en-us' => 'CurrentSpeed',
'zh-cn' => '即时速度', 'zh-cn' => '即时速度',
'ja' => 'インスタントスピード',
], ],
'Expect' => [ 'Expect' => [
'en-us' => 'Expect', 'en-us' => 'Expect',
'zh-cn' => '预计还要', 'zh-cn' => '预计还要',
'ja' => '期待される',
], ],
'EndAt' => [ 'EndAt' => [
'en-us' => 'End At', 'en-us' => 'End At',
'zh-cn' => '结束于', 'zh-cn' => '结束于',
'ja' => 'で終了',
], ],
'UploadErrorUpAgain' => [ 'UploadErrorUpAgain' => [
'en-us' => 'Maybe error, do upload again.', 'en-us' => 'Maybe error, do upload again.',
'zh-cn' => '可能出错,重新上传。', 'zh-cn' => '可能出错,重新上传。',
'ja' => '間違っている可能性があります。もう一度アップロードしてください。',
], ],
'UploadComplete' => [ 'UploadComplete' => [
'en-us' => 'Upload Complete', 'en-us' => 'Upload Complete',
'zh-cn' => '上传完成', 'zh-cn' => '上传完成',
'ja' => 'アップロード完了',
], ],
'UploadFail23' => [ 'UploadFail23' => [
'en-us' => 'Upload Fail, contain #.', 'en-us' => 'Upload Fail, contain #.',
'zh-cn' => '目录或文件名含有#,上传失败。', 'zh-cn' => '目录或文件名含有#,上传失败。',
'ja' => 'ディレクトリまたはファイル名に#が含まれています。アップロードに失敗しました。',
], ],
'defaultSitename' => [ 'defaultSitename' => [
'en-us' => 'Set sitename in Environments', 'en-us' => 'OneManager',
'zh-cn' => '请在环境变量添加sitename', 'zh-cn' => 'OneManager',
'ja' => 'OneManager',
], ],
'MayinEnv' => [ 'MayinEnv' => [
'en-us' => 'The \'Onedrive_ver\' may in Environments', 'en-us' => 'The \'Onedrive_ver\' may in Config',
'zh-cn' => 'Onedrive_ver应该已经写入环境变量', 'zh-cn' => 'Onedrive_ver应该已经写入',
'ja' => 'Onedrive_verは環境変数に書き込まれている必要があります',
], ],
'Wait' => [ 'Wait' => [
'en-us' => 'Wait', 'en-us' => 'Wait',
'zh-cn' => '稍等', 'zh-cn' => '稍等',
'ja' => 'ちょっと待って',
], ],
'WaitJumpIndex' => [ 'WaitJumpIndex' => [
'en-us' => 'Wait 5s jump to Home page', 'en-us' => 'Wait 5s jump to Home page',
'zh-cn' => '等5s跳到首页', 'zh-cn' => '等5s跳到首页',
'ja' => '5秒待ってホームページにジャンプします',
], ],
'JumptoOffice' => [ 'JumptoOffice' => [
'en-us' => 'Login Office and Get a refresh_token', 'en-us' => 'Login Office and Get a refresh_token',
'zh-cn' => '跳转到Office登录获取refresh_token', 'zh-cn' => '跳转到Office登录获取refresh_token',
'ja' => 'Officeにジャンプしてログインし、refresh_tokenを取得します',
], ],
'OndriveVerMS' => [ 'OndriveVerMS' => [
'en-us' => 'default(Onedrive, Onedrive for business)', 'en-us' => 'default(Onedrive, Onedrive for business)',
'zh-cn' => '默认(支持商业版与个人版)', 'zh-cn' => '默认(支持商业版与个人版)',
'ja' => 'デフォルト(商用版および個人版をサポート)',
], ],
'OndriveVerCN' => [ 'OndriveVerCN' => [
'en-us' => 'Onedrive in China', 'en-us' => 'Onedrive in China',
'zh-cn' => '世纪互联版', 'zh-cn' => '世纪互联版',
'ja' => '中国のOnedrive',
], ],
'OndriveVerMSC' =>[ 'OndriveVerMSC' =>[
'en-us' => 'default but use customer app id & secret', 'en-us' => 'default but use customer app id & secret',
'zh-cn' => '国际版自己申请应用ID与机密', 'zh-cn' => '国际版自己申请应用ID与机密',
'ja' => '国際版、アプリケーションIDとシークレットを自分で申請する',
], ],
'GetSecretIDandKEY' =>[ 'GetSecretIDandKEY' =>[
'en-us' => 'Get customer app id & secret', 'en-us' => 'Get customer app id & secret',
'zh-cn' => '申请应用ID与机密', 'zh-cn' => '申请应用ID与机密',
'ja' => 'アプリケーションIDとシークレット',
], ],
'Reflesh' => [ 'Reflesh' => [
'en-us' => 'Reflesh', 'en-us' => 'Reflesh',
'zh-cn' => '刷新', 'zh-cn' => '刷新',
'ja' => '再表示',
], ],
'SelectLanguage' => [ 'SelectLanguage' => [
'en-us' => 'Select Language', 'en-us' => 'Select Language',
'zh-cn' => '选择语言', 'zh-cn' => '选择语言',
'ja' => '言語を選択してください',
],
'RefreshCache' => [
'en-us' => 'RefreshCache',
'zh-cn' => '刷新缓存',
'ja' => 'キャッシュを再構築',
], ],
]; ];
?>

863
function/common.php Normal file
View File

@ -0,0 +1,863 @@
<?php
function getcache($str)
{
$cache = null;
$cache = new \Doctrine\Common\Cache\FilesystemCache(sys_get_temp_dir(), '.Onedrive');
return $cache->fetch($str);
}
function savecache($key, $value, $exp = 3300)
{
$cache = null;
$cache = new \Doctrine\Common\Cache\FilesystemCache(sys_get_temp_dir(), '.Onedrive');
$cache->save($key, $value, $exp);
}
function getconstStr($str)
{
global $constStr;
$constStr['language'] = $_COOKIE['language'];
if ($constStr['language']=='') $constStr['language'] = getConfig('language');
if ($constStr['language']=='') $constStr['language'] = 'en-us';
if ($constStr[$str][$constStr['language']]!='') return $constStr[$str][$constStr['language']];
return $constStr[$str]['en-us'];
}
function config_oauth()
{
global $constStr;
$_SERVER['sitename'] = getConfig('sitename');
if (empty($_SERVER['sitename'])) $_SERVER['sitename'] = getconstStr('defaultSitename');
$_SERVER['redirect_uri'] = 'https://scfonedrive.github.io';
if (getConfig('Onedrive_ver')=='MS') {
// MS
// https://portal.azure.com
$_SERVER['client_id'] = '4da3e7f2-bf6d-467c-aaf0-578078f0bf7c';
$_SERVER['client_secret'] = '7/+ykq2xkfx:.DWjacuIRojIaaWL0QI6';
$_SERVER['oauth_url'] = 'https://login.microsoftonline.com/common/oauth2/v2.0/';
$_SERVER['api_url'] = 'https://graph.microsoft.com/v1.0/me/drive/root';
$_SERVER['scope'] = 'https://graph.microsoft.com/Files.ReadWrite.All offline_access';
}
if (getConfig('Onedrive_ver')=='CN') {
// CN
// https://portal.azure.cn
$_SERVER['client_id'] = '04c3ca0b-8d07-4773-85ad-98b037d25631';
$_SERVER['client_secret'] = 'h8@B7kFVOmj0+8HKBWeNTgl@pU/z4yLB';
$_SERVER['oauth_url'] = 'https://login.partner.microsoftonline.cn/common/oauth2/v2.0/';
$_SERVER['api_url'] = 'https://microsoftgraph.chinacloudapi.cn/v1.0/me/drive/root';
$_SERVER['scope'] = 'https://microsoftgraph.chinacloudapi.cn/Files.ReadWrite.All offline_access';
}
if (getConfig('Onedrive_ver')=='MSC') {
// MS Customer
// https://portal.azure.com
$_SERVER['client_id'] = getConfig('client_id');
$_SERVER['client_secret'] = getConfig('client_secret');
$_SERVER['oauth_url'] = 'https://login.microsoftonline.com/common/oauth2/v2.0/';
$_SERVER['api_url'] = 'https://graph.microsoft.com/v1.0/me/drive/root';
$_SERVER['scope'] = 'https://graph.microsoft.com/Files.ReadWrite.All offline_access';
}
$_SERVER['client_secret'] = urlencode($_SERVER['client_secret']);
$_SERVER['scope'] = urlencode($_SERVER['scope']);
}
function getListpath($domain)
{
$domain_path = getConfig('domain_path');
/*$tmp_path='';
if ($domain_path!='') {
$tmp = explode("|",$domain_path);
foreach ($tmp as $multidomain_paths){
$pos = strpos($multidomain_paths,":");
$tmp_path = path_format(substr($multidomain_paths,$pos+1));
if (substr($multidomain_paths,0,$pos)==$host_name) $private_path=$tmp_path;
}
}*/
if (isset($domain_path[$domain])) return spurlencode($domain_path[$domain],'/');
return spurlencode(getConfig('public_path'),'/');
}
function path_format($path)
{
$path = '/' . $path;
while (strpos($path, '//') !== FALSE) {
$path = str_replace('//', '/', $path);
}
return $path;
}
function spurlencode($str,$splite='')
{
$str = str_replace(' ', '%20',$str);
$tmp='';
if ($splite!='') {
$tmparr=explode($splite,$str);
for($x=0;$x<count($tmparr);$x++) {
if ($tmparr[$x]!='') $tmp .= $splite . urlencode($tmparr[$x]);
}
} else {
$tmp = urlencode($str);
}
$tmp = str_replace('%2520', '%20',$tmp);
return $tmp;
}
function is_guestup_path($path)
{
if (path_format('/'.path_format(urldecode($_SERVER['list_path'].path_format($path))).'/')==path_format('/'.path_format(getConfig('guestup_path')).'/')&&getConfig('guestup_path')!='') return 1;
return 0;
}
function curl_request($url, $data = false, $headers = [])
{
if (!isset($headers['Accept'])) $headers['Accept'] = '*/*';
if (!isset($headers['Referer'])) $headers['Referer'] = $url;
if (!isset($headers['Content-Type'])) $headers['Content-Type'] = 'application/x-www-form-urlencoded';
$sendHeaders = array();
foreach ($headers as $headerName => $headerVal) {
$sendHeaders[] = $headerName . ': ' . $headerVal;
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
if ($data !== false) {
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
}
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_HTTPHEADER, $sendHeaders);
$response['body'] = curl_exec($ch);
$response['stat'] = curl_getinfo($ch,CURLINFO_HTTP_CODE);
curl_close($ch);
return $response;
}
function clearbehindvalue($path,$page1,$maxpage,$pageinfocache)
{
for ($page=$page1+1;$page<$maxpage;$page++) {
$pageinfocache['nextlink_' . $path . '_page_' . $page] = '';
}
return $pageinfocache;
}
function comppass($pass)
{
if ($_POST['password1'] !== '') if (md5($_POST['password1']) === $pass ) {
date_default_timezone_set('UTC');
$_SERVER['Set-Cookie'] = 'password='.$pass.'; expires='.date(DATE_COOKIE,strtotime('+1hour'));
date_default_timezone_set(get_timezone($_COOKIE['timezone']));
return 2;
}
if ($_COOKIE['password'] !== '') if ($_COOKIE['password'] === $pass ) return 3;
return 4;
}
function encode_str_replace($str)
{
$str = str_replace('&','&amp;',$str);
$str = str_replace('+','%2B',$str);
$str = str_replace('#','%23',$str);
return $str;
}
function gethiddenpass($path,$passfile)
{
$ispassfile = fetch_files(spurlencode(path_format($path . '/' . $passfile),'/'));
//echo $path . '<pre>' . json_encode($ispassfile, JSON_PRETTY_PRINT) . '</pre>';
if (isset($ispassfile['file'])) {
$arr = curl_request($ispassfile['@microsoft.graph.downloadUrl']);
if ($arr['stat']==200) {
$passwordf=explode("\n",$arr['body']);
$password=$passwordf[0];
$password=md5($password);
return $password;
} else {
//return md5('DefaultP@sswordWhenNetworkError');
return md5( md5(time()).rand(1000,9999) );
}
} else {
if ($path !== '' ) {
$path = substr($path,0,strrpos($path,'/'));
return gethiddenpass($path,$passfile);
} else {
return '';
}
}
return md5('DefaultP@sswordWhenNetworkError');
}
function get_timezone($timezone = '8')
{
$timezones = array(
'-12'=>'Pacific/Kwajalein',
'-11'=>'Pacific/Samoa',
'-10'=>'Pacific/Honolulu',
'-9'=>'America/Anchorage',
'-8'=>'America/Los_Angeles',
'-7'=>'America/Denver',
'-6'=>'America/Mexico_City',
'-5'=>'America/New_York',
'-4'=>'America/Caracas',
'-3.5'=>'America/St_Johns',
'-3'=>'America/Argentina/Buenos_Aires',
'-2'=>'America/Noronha',
'-1'=>'Atlantic/Azores',
'0'=>'UTC',
'1'=>'Europe/Paris',
'2'=>'Europe/Helsinki',
'3'=>'Europe/Moscow',
'3.5'=>'Asia/Tehran',
'4'=>'Asia/Baku',
'4.5'=>'Asia/Kabul',
'5'=>'Asia/Karachi',
'5.5'=>'Asia/Calcutta', //Asia/Colombo
'6'=>'Asia/Dhaka',
'6.5'=>'Asia/Rangoon',
'7'=>'Asia/Bangkok',
'8'=>'Asia/Shanghai',
'9'=>'Asia/Tokyo',
'9.5'=>'Australia/Darwin',
'10'=>'Pacific/Guam',
'11'=>'Asia/Magadan',
'12'=>'Asia/Kamchatka'
);
if ($timezone=='') $timezone = '8';
return $timezones[$timezone];
}
function message($message, $title = 'Message', $statusCode = 200)
{
return output('<html><meta charset=utf-8><body><h1>' . $title . '</h1><p>' . $message . '</p></body></html>', $statusCode);
}
function needUpdate()
{
if ($_SERVER['admin']) {
$current_ver = file_get_contents(__DIR__ . '/version');
$current_ver = substr($current_ver, strpos($current_ver, '.')+1);
$current_ver = explode(urldecode('%0A'),$current_ver)[0];
$current_ver = explode(urldecode('%0D'),$current_ver)[0];
$github_version = file_get_contents('https://raw.githubusercontent.com/qkqpttgf/OneManager-php/master/version');
$github_ver = substr($github_version, strpos($github_version, '.')+1);
$github_ver = explode(urldecode('%0A'),$github_ver)[0];
$github_ver = explode(urldecode('%0D'),$github_ver)[0];
if ($current_ver != $github_ver) {
$_SERVER['github_version'] = $github_version;
return 1;
}
}
return 0;
}
function output($body, $statusCode = 200, $headers = ['Content-Type' => 'text/html'], $isBase64Encoded = false)
{
return [
'isBase64Encoded' => $isBase64Encoded,
'statusCode' => $statusCode,
'headers' => $headers,
'body' => $body
];
}
function passhidden($path)
{
$path = str_replace('+','%2B',$path);
$path = str_replace('&amp;','&', path_format(urldecode($path)));
if (getConfig('passfile') != '') {
if (substr($path,-1)=='/') $path=substr($path,0,-1);
$hiddenpass=gethiddenpass($path,getConfig('passfile'));
if ($hiddenpass != '') {
return comppass($hiddenpass);
} else {
return 1;
}
} else {
return 0;
}
return 4;
}
function size_format($byte)
{
$i = 0;
while (abs($byte) >= 1024) {
$byte = $byte / 1024;
$i++;
if ($i == 3) break;
}
$units = array('B', 'KB', 'MB', 'GB', 'TB');
$ret = round($byte, 2);
return ($ret . ' ' . $units[$i]);
}
function time_format($ISO)
{
$ISO = str_replace('T', ' ', $ISO);
$ISO = str_replace('Z', ' ', $ISO);
//return $ISO;
return date('Y-m-d H:i:s',strtotime($ISO . " UTC"));
}
function get_thumbnails_url($path = '/')
{
$path1 = path_format($path);
$path = path_format($_SERVER['list_path'] . path_format($path));
$url = $_SERVER['api_url'];
if ($path !== '/') {
$url .= ':' . $path;
if (substr($url,-1)=='/') $url=substr($url,0,-1);
}
$url .= ':/thumbnails/0/medium';
$files = json_decode(curl_request($url, false, ['Authorization' => 'Bearer ' . $_SERVER['access_token']])['body'], true);
if (isset($files['url'])) return output($files['url']);
return output('', 404);
}
function bigfileupload($path)
{
$path1 = path_format($_SERVER['list_path'] . path_format($path));
if (substr($path1,-1)=='/') $path1=substr($path1,0,-1);
if ($_GET['upbigfilename']!=''&&$_GET['filesize']>0) {
$fileinfo['name'] = $_GET['upbigfilename'];
$fileinfo['size'] = $_GET['filesize'];
$fileinfo['lastModified'] = $_GET['lastModified'];
$filename = spurlencode( $fileinfo['name'] );
$cachefilename = '.' . $fileinfo['lastModified'] . '_' . $fileinfo['size'] . '_' . $filename . '.tmp';
$getoldupinfo=fetch_files(path_format($path . '/' . $cachefilename));
//echo json_encode($getoldupinfo, JSON_PRETTY_PRINT);
if (isset($getoldupinfo['file'])&&$getoldupinfo['size']<5120) {
$getoldupinfo_j = curl_request($getoldupinfo['@microsoft.graph.downloadUrl']);
$getoldupinfo = json_decode($getoldupinfo_j , true);
if ( json_decode( curl_request($getoldupinfo['uploadUrl']), true)['@odata.context']!='' ) return output($getoldupinfo_j);
}
if (!$_SERVER['admin']) $filename = spurlencode( $fileinfo['name'] ) . '.scfupload';
$response=MSAPI('createUploadSession',path_format($path1 . '/' . $filename),'{"item": { "@microsoft.graph.conflictBehavior": "fail" }}',$_SERVER['access_token']);
$responsearry = json_decode($response['body'],true);
if (isset($responsearry['error'])) return output($response['body'], $response['stat']);
$fileinfo['uploadUrl'] = $responsearry['uploadUrl'];
MSAPI('PUT', path_format($path1 . '/' . $cachefilename), json_encode($fileinfo, JSON_PRETTY_PRINT), $_SERVER['access_token'])['body'];
return output($response['body'], $response['stat']);
}
return output('error', 400);
}
function main($path)
{
global $exts;
global $constStr;
config_oauth();
$_SERVER['list_path'] = getListpath($_SERVER['HTTP_HOST']);
if ($_SERVER['list_path']=='') $_SERVER['list_path'] = '/';
$_SERVER['is_guestup_path'] = is_guestup_path($path);
$_SERVER['PHP_SELF'] = path_format($_SERVER['base_path'] . $path);
$_SERVER['ajax']=0;
if (isset($_SERVER['HTTP_X_REQUESTED_WITH'])) if ($_SERVER['HTTP_X_REQUESTED_WITH']=='XMLHttpRequest') $_SERVER['ajax']=1;
$refresh_token = getConfig('refresh_token');
if (!$refresh_token) return get_refresh_token();
if (getConfig('adminloginpage')=='') {
$adminloginpage = 'admin';
} else {
$adminloginpage = getConfig('adminloginpage');
}
if ($_GET[$adminloginpage]) {
if ($_GET['preview']) {
$url = $_SERVER['PHP_SELF'] . '?preview';
} else {
$url = path_format($_SERVER['PHP_SELF'] . '/');
}
if (getConfig('admin')!='') {
if ($_POST['password1']==getConfig('admin')) {
return adminform('admin',md5($_POST['password1']),$url);
} else return adminform();
} else {
return output('', 302, [ 'Location' => $url ]);
}
}
if (getConfig('admin')!='')
if ( $_COOKIE['admin']==md5(getConfig('admin')) || $_POST['password1']==getConfig('admin') ) {
$_SERVER['admin']=1;
$_SERVER['needUpdate'] = needUpdate();
} else {
$_SERVER['admin']=0;
}
if ($_GET['setup'])
if ($_SERVER['admin']) {
// setup Environments. 设置,对环境变量操作
return EnvOpt($_SERVER['function_name'], $_SERVER['needUpdate']);
} else {
$url = path_format($_SERVER['PHP_SELF'] . '/');
return output('<script>alert(\''.getconstStr('SetSecretsFirst').'\');</script>', 302, [ 'Location' => $url ]);
}
$_SERVER['retry'] = 0;
if (!($_SERVER['access_token'] = getcache('access_token'))) {
$ret = json_decode(curl_request(
$_SERVER['oauth_url'] . 'token',
'client_id='. $_SERVER['client_id'] .'&client_secret='. $_SERVER['client_secret'] .'&grant_type=refresh_token&requested_token_use=on_behalf_of&refresh_token=' . $refresh_token
)['body'], true);
if (!isset($ret['access_token'])) {
error_log('failed to get access_token. response' . json_encode($ret));
throw new Exception('failed to get access_token.');
}
$_SERVER['access_token'] = $ret['access_token'];
savecache('access_token', $_SERVER['access_token']);
}
if ($_SERVER['ajax']) {
if ($_GET['action']=='del_upload_cache'&&substr($_GET['filename'],-4)=='.tmp') {
// del '.tmp' without login. 无需登录即可删除.tmp后缀文件
$tmp = MSAPI('DELETE',path_format(path_format($_SERVER['list_path'] . path_format($path)) . '/' . spurlencode($_GET['filename']) ),'',$_SERVER['access_token']);
$path1 = path_format($_SERVER['list_path'] . path_format($path));
savecache('path_' . $path1, json_decode('{}',true), 1);
return output($tmp['body'],$tmp['stat']);
}
if ($_GET['action']=='uploaded_rename') {
// rename .scfupload file without login.
// 无需登录即可重命名.scfupload后缀文件filemd5为用户提交可被构造问题不大以后处理
$oldname = spurlencode($_GET['filename']);
$pos = strrpos($oldname, '.');
if ($pos>0) $ext = strtolower(substr($oldname, $pos));
$oldname = path_format(path_format($_SERVER['list_path'] . path_format($path)) . '/' . $oldname . '.scfupload' );
$data = '{"name":"' . $_GET['filemd5'] . $ext . '"}';
//echo $oldname .'<br>'. $data;
$tmp = MSAPI('PATCH',$oldname,$data,$_SERVER['access_token']);
if ($tmp['stat']==409) MSAPI('DELETE',$oldname,'',$_SERVER['access_token'])['body'];
$path1 = path_format($_SERVER['list_path'] . path_format($path));
savecache('path_' . $path1, json_decode('{}',true), 1);
return output($tmp['body'],$tmp['stat']);
}
if ($_GET['action']=='upbigfile') return bigfileupload($path);
}
if ($_SERVER['admin']) {
$tmp = adminoperate($path);
if ($tmp['statusCode'] > 0) {
$path1 = path_format($_SERVER['list_path'] . path_format($path));
savecache('path_' . $path1, json_decode('{}',true), 1);
return $tmp;
}
} else {
if ($_SERVER['ajax']) return output(getconstStr('RefleshtoLogin'),401);
}
$_SERVER['ishidden'] = passhidden($path);
if ($_GET['thumbnails']) {
if ($_SERVER['ishidden']<4) {
if (in_array(strtolower(substr($path, strrpos($path, '.') + 1)), $exts['img'])) {
return get_thumbnails_url($path);
} else return output(json_encode($exts['img']),400);
} else return output('',401);
}
$files = list_files($path);
if (isset($files['file']) && !$_GET['preview']) {
// is file && not preview mode
if ($_SERVER['ishidden']<4) return output('', 302, [ 'Location' => $files['@microsoft.graph.downloadUrl'] ]);
}
if ( isset($files['folder']) || isset($files['file']) ) {
return render_list($path, $files);
} else {
return message('<div style="margin:8px;">' . $files['error']['message'] . '</div><a href="javascript:history.back(-1)">'.getconstStr('Back').'</a>', $files['error']['code'], $files['error']['stat']);
}
}
function list_files($path)
{
$path = path_format($path);
if ($_SERVER['is_guestup_path']&&!$_SERVER['admin']) {
$files = json_decode('{"folder":{}}', true);
} elseif ($_SERVER['ishidden']==4) {
$files = json_decode('{"folder":{}}', true);
} else {
$files = fetch_files($path);
}
if ( isset($files['folder']) || isset($files['file']) || isset($files['error']) ) {
return $files;
} else {
error_log( json_encode($files) . ' Network Error<br>' );
$_SERVER['retry']++;
if ($_SERVER['retry'] < 3) {
return list_files($path);
} else return $files;
}
}
function adminform($name = '', $pass = '', $path = '')
{
global $constStr;
$statusCode = 401;
$html = '<html><head><title>'.getconstStr('AdminLogin').'</title><meta charset=utf-8></head>';
if ($name!=''&&$pass!='') {
$html .= '<body>'.getconstStr('LoginSuccess').'</body></html>';
$statusCode = 302;
date_default_timezone_set('UTC');
$header = [
'Set-Cookie' => $name.'='.$pass.'; path=/; expires='.date(DATE_COOKIE,strtotime('+1hour')),
'Location' => $path,
'Content-Type' => 'text/html'
];
return output($html,$statusCode,$header);
}
$html .= '
<body>
<div>
<center><h4>'.getconstStr('InputPassword').'</h4>
<form action="" method="post">
<div>
<input name="password1" type="password"/>
<input type="submit" value="'.getconstStr('Login').'">
</div>
</form>
</center>
</div>
';
$html .= '</body></html>';
return output($html,$statusCode);
}
function adminoperate($path)
{
global $constStr;
$path1 = path_format($_SERVER['list_path'] . path_format($path));
if (substr($path1,-1)=='/') $path1=substr($path1,0,-1);
$tmparr['statusCode'] = 0;
if ($_GET['rename_newname']!=$_GET['rename_oldname'] && $_GET['rename_newname']!='') {
// rename 重命名
$oldname = spurlencode($_GET['rename_oldname']);
$oldname = path_format($path1 . '/' . $oldname);
$data = '{"name":"' . $_GET['rename_newname'] . '"}';
//echo $oldname;
$result = MSAPI('PATCH',$oldname,$data,$_SERVER['access_token']);
//savecache('path_' . $path1, json_decode('{}',true), 1);
return output($result['body'], $result['stat']);
}
if ($_GET['delete_name']!='') {
// delete 删除
$filename = spurlencode($_GET['delete_name']);
$filename = path_format($path1 . '/' . $filename);
//echo $filename;
$result = MSAPI('DELETE', $filename, '', $_SERVER['access_token']);
//savecache('path_' . $path1, json_decode('{}',true), 1);
return output($result['body'], $result['stat']);
}
if ($_GET['operate_action']==getconstStr('encrypt')) {
// encrypt 加密
if (getConfig('passfile')=='') return message(getconstStr('SetpassfileBfEncrypt'),'',403);
if ($_GET['encrypt_folder']=='/') $_GET['encrypt_folder']=='';
$foldername = spurlencode($_GET['encrypt_folder']);
$filename = path_format($path1 . '/' . $foldername . '/' . getConfig('passfile'));
//echo $foldername;
$result = MSAPI('PUT', $filename, $_GET['encrypt_newpass'], $_SERVER['access_token']);
//savecache('path_' . $path1, json_decode('{}',true), 1);
return output($result['body'], $result['stat']);
}
if ($_GET['move_folder']!='') {
// move 移动
$moveable = 1;
if ($path == '/' && $_GET['move_folder'] == '/../') $moveable=0;
if ($_GET['move_folder'] == $_GET['move_name']) $moveable=0;
if ($moveable) {
$filename = spurlencode($_GET['move_name']);
$filename = path_format($path1 . '/' . $filename);
$foldername = path_format('/'.urldecode($path1).'/'.$_GET['move_folder']);
$data = '{"parentReference":{"path": "/drive/root:'.$foldername.'"}}';
$result = MSAPI('PATCH', $filename, $data, $_SERVER['access_token']);
//savecache('path_' . $path1, json_decode('{}',true), 1);
if ($_GET['move_folder'] == '/../') $path2 = path_format( substr($path1, 0, strrpos($path1, '/')) . '/' );
else $path2 = path_format( $path1 . '/' . $_GET['move_folder'] . '/' );
savecache('path_' . $path2, json_decode('{}',true), 1);
return output($result['body'], $result['stat']);
} else {
return output('{"error":"Can not Move!"}', 403);
}
}
if ($_POST['editfile']!='') {
// edit 编辑
$data = $_POST['editfile'];
/*TXT一般不会超过4M不用二段上传
$filename = $path1 . ':/createUploadSession';
$response=MSAPI('POST',$filename,'{"item": { "@microsoft.graph.conflictBehavior": "replace" }}',$_SERVER['access_token']);
$uploadurl=json_decode($response,true)['uploadUrl'];
echo MSAPI('PUT',$uploadurl,$data,$_SERVER['access_token']);*/
$result = MSAPI('PUT', $path1, $data, $_SERVER['access_token'])['body'];
//echo $result;
$resultarry = json_decode($result,true);
if (isset($resultarry['error'])) return message($resultarry['error']['message']. '<hr><a href="javascript:history.back(-1)">上一页</a>','Error',403);
}
if ($_GET['create_name']!='') {
// create 新建
if ($_GET['create_type']=='file') {
$filename = spurlencode($_GET['create_name']);
$filename = path_format($path1 . '/' . $filename);
$result = MSAPI('PUT', $filename, $_GET['create_text'], $_SERVER['access_token']);
}
if ($_GET['create_type']=='folder') {
$data = '{ "name": "' . $_GET['create_name'] . '", "folder": { }, "@microsoft.graph.conflictBehavior": "rename" }';
$result = MSAPI('children', $path1, $data, $_SERVER['access_token']);
}
//savecache('path_' . $path1, json_decode('{}',true), 1);
return output($result['body'], $result['stat']);
}
if ($_GET['RefreshCache']) {
//savecache('path_' . $path1, json_decode('{}',true), 1);
return output('<meta http-equiv="refresh" content="2;URL=./">'.getconstStr('RefreshCache'), 302);
}
return $tmparr;
}
function MSAPI($method, $path, $data = '', $access_token)
{
if (substr($path,0,7) == 'http://' or substr($path,0,8) == 'https://') {
$url=$path;
$lenth=strlen($data);
$headers['Content-Length'] = $lenth;
$lenth--;
$headers['Content-Range'] = 'bytes 0-' . $lenth . '/' . $headers['Content-Length'];
} else {
$url = $_SERVER['api_url'];
if ($path=='' or $path=='/') {
$url .= '/';
} else {
$url .= ':' . $path;
if (substr($url,-1)=='/') $url=substr($url,0,-1);
}
if ($method=='PUT') {
if ($path=='' or $path=='/') {
$url .= 'content';
} else {
$url .= ':/content';
}
$headers['Content-Type'] = 'text/plain';
} elseif ($method=='PATCH') {
$headers['Content-Type'] = 'application/json';
} elseif ($method=='POST') {
$headers['Content-Type'] = 'application/json';
} elseif ($method=='DELETE') {
$headers['Content-Type'] = 'application/json';
} else {
if ($path=='' or $path=='/') {
$url .= $method;
} else {
$url .= ':/' . $method;
}
$method='POST';
$headers['Content-Type'] = 'application/json';
}
}
$headers['Authorization'] = 'Bearer ' . $access_token;
if (!isset($headers['Accept'])) $headers['Accept'] = '*/*';
if (!isset($headers['Referer'])) $headers['Referer'] = $url;
$sendHeaders = array();
foreach ($headers as $headerName => $headerVal) {
$sendHeaders[] = $headerName . ': ' . $headerVal;
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST,$method);
curl_setopt($ch, CURLOPT_POSTFIELDS,$data);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_HTTPHEADER, $sendHeaders);
$response['body'] = curl_exec($ch);
$response['stat'] = curl_getinfo($ch,CURLINFO_HTTP_CODE);
curl_close($ch);
error_log($response['stat'].'
'.$response['body'].'
');
return $response;
}
function fetch_files($path = '/')
{
$path1 = path_format($path);
$path = path_format($_SERVER['list_path'] . path_format($path));
if (!($files = getcache('path_' . $path))) {
// https://docs.microsoft.com/en-us/graph/api/driveitem-get?view=graph-rest-1.0
// https://docs.microsoft.com/zh-cn/graph/api/driveitem-put-content?view=graph-rest-1.0&tabs=http
// https://developer.microsoft.com/zh-cn/graph/graph-explorer
$url = $_SERVER['api_url'];
if ($path !== '/') {
$url .= ':' . $path;
if (substr($url,-1)=='/') $url=substr($url,0,-1);
}
$url .= '?expand=children(select=name,size,file,folder,parentReference,lastModifiedDateTime)';
$arr = curl_request($url, false, ['Authorization' => 'Bearer ' . $_SERVER['access_token']]);
if ($arr['stat']<500) {
$files = json_decode($arr['body'], true);
// echo $path . '<br><pre>' . json_encode($files, JSON_PRETTY_PRINT) . '</pre>';
if (isset($files['folder'])) {
if ($files['folder']['childCount']>200) {
// files num > 200 , then get nextlink
$page = $_POST['pagenum']==''?1:$_POST['pagenum'];
$files=fetch_files_children($files, $path, $page);
} else {
// files num < 200 , then cache
savecache('path_' . $path, $files);
}
}
if (isset($files['error'])) {
$files['error']['stat'] = $arr['stat'];
}
} else {
error_log($arr['body']);
$files = json_decode( '{"unknownError":{ "stat":'.$arr['stat'].',"message":"'.$arr['body'].'"}}', true);
}
}
return $files;
}
function fetch_files_children($files, $path, $page)
{
$cachefilename = '.SCFcache_'.$_SERVER['function_name'];
$maxpage = ceil($files['folder']['childCount']/200);
if (!($files['children'] = getcache('files_' . $path . '_page_' . $page))) {
// down cache file get jump info. 下载cache文件获取跳页链接
$cachefile = fetch_files(path_format($path1 . '/' .$cachefilename));
if ($cachefile['size']>0) {
$pageinfo = curl_request($cachefile['@microsoft.graph.downloadUrl'])['body'];
$pageinfo = json_decode($pageinfo,true);
for ($page4=1;$page4<$maxpage;$page4++) {
savecache('nextlink_' . $path . '_page_' . $page4, $pageinfo['nextlink_' . $path . '_page_' . $page4]);
$pageinfocache['nextlink_' . $path . '_page_' . $page4] = $pageinfo['nextlink_' . $path . '_page_' . $page4];
}
}
$pageinfochange=0;
for ($page1=$page;$page1>=1;$page1--) {
$page3=$page1-1;
$url = getcache('nextlink_' . $path . '_page_' . $page3);
if ($url == '') {
if ($page1==1) {
$url = $_SERVER['api_url'];
if ($path !== '/') {
$url .= ':' . $path;
if (substr($url,-1)=='/') $url=substr($url,0,-1);
$url .= ':/children?$select=name,size,file,folder,parentReference,lastModifiedDateTime';
} else {
$url .= '/children?$select=name,size,file,folder,parentReference,lastModifiedDateTime';
}
$children = json_decode(curl_request($url, false, ['Authorization' => 'Bearer ' . $_SERVER['access_token']])['body'], true);
// echo $url . '<br><pre>' . json_encode($children, JSON_PRETTY_PRINT) . '</pre>';
savecache('files_' . $path . '_page_' . $page1, $children['value']);
$nextlink=getcache('nextlink_' . $path . '_page_' . $page1);
if ($nextlink!=$children['@odata.nextLink']) {
savecache('nextlink_' . $path . '_page_' . $page1, $children['@odata.nextLink']);
$pageinfocache['nextlink_' . $path . '_page_' . $page1] = $children['@odata.nextLink'];
$pageinfocache = clearbehindvalue($path,$page1,$maxpage,$pageinfocache);
$pageinfochange = 1;
}
$url = $children['@odata.nextLink'];
for ($page2=$page1+1;$page2<=$page;$page2++) {
sleep(1);
$children = json_decode(curl_request($url, false, ['Authorization' => 'Bearer ' . $_SERVER['access_token']])['body'], true);
savecache('files_' . $path . '_page_' . $page2, $children['value']);
$nextlink=getcache('nextlink_' . $path . '_page_' . $page2);
if ($nextlink!=$children['@odata.nextLink']) {
savecache('nextlink_' . $path . '_page_' . $page2, $children['@odata.nextLink']);
$pageinfocache['nextlink_' . $path . '_page_' . $page2] = $children['@odata.nextLink'];
$pageinfocache = clearbehindvalue($path,$page2,$maxpage,$pageinfocache);
$pageinfochange = 1;
}
$url = $children['@odata.nextLink'];
}
//echo $url . '<br><pre>' . json_encode($children, JSON_PRETTY_PRINT) . '</pre>';
$files['children'] = $children['value'];
$files['folder']['page']=$page;
$pageinfocache['filenum'] = $files['folder']['childCount'];
$pageinfocache['dirsize'] = $files['size'];
$pageinfocache['cachesize'] = $cachefile['size'];
$pageinfocache['size'] = $files['size']-$cachefile['size'];
if ($pageinfochange == 1) MSAPI('PUT', path_format($path.'/'.$cachefilename), json_encode($pageinfocache, JSON_PRETTY_PRINT), $_SERVER['access_token'])['body'];
return $files;
}
} else {
for ($page2=$page3+1;$page2<=$page;$page2++) {
sleep(1);
$children = json_decode(curl_request($url, false, ['Authorization' => 'Bearer ' . $_SERVER['access_token']])['body'], true);
savecache('files_' . $path . '_page_' . $page2, $children['value'], 3300);
$nextlink=getcache('nextlink_' . $path . '_page_' . $page2);
if ($nextlink!=$children['@odata.nextLink']) {
savecache('nextlink_' . $path . '_page_' . $page2, $children['@odata.nextLink'], 3300);
$pageinfocache['nextlink_' . $path . '_page_' . $page2] = $children['@odata.nextLink'];
$pageinfocache = clearbehindvalue($path,$page2,$maxpage,$pageinfocache);
$pageinfochange = 1;
}
$url = $children['@odata.nextLink'];
}
//echo $url . '<br><pre>' . json_encode($children, JSON_PRETTY_PRINT) . '</pre>';
$files['children'] = $children['value'];
$files['folder']['page']=$page;
$pageinfocache['filenum'] = $files['folder']['childCount'];
$pageinfocache['dirsize'] = $files['size'];
$pageinfocache['cachesize'] = $cachefile['size'];
$pageinfocache['size'] = $files['size']-$cachefile['size'];
if ($pageinfochange == 1) MSAPI('PUT', path_format($path.'/'.$cachefilename), json_encode($pageinfocache, JSON_PRETTY_PRINT), $_SERVER['access_token'])['body'];
return $files;
}
}
} else {
$files['folder']['page']=$page;
for ($page4=1;$page4<=$maxpage;$page4++) {
if (!($url = getcache('nextlink_' . $path . '_page_' . $page4))) {
if ($files['folder'][$path.'_'.$page4]!='') savecache('nextlink_' . $path . '_page_' . $page4, $files['folder'][$path.'_'.$page4]);
} else {
$files['folder'][$path.'_'.$page4] = $url;
}
}
}
return $files;
}
function render_list($path, $files)
{
global $exts;
global $constStr;
$path = str_replace('%20','%2520',$path);
$path = str_replace('+','%2B',$path);
$path = str_replace('&','&amp;',path_format(urldecode($path))) ;
$path = str_replace('%20',' ',$path);
$path = str_replace('#','%23',$path);
$p_path='';
if ($path !== '/') {
if (isset($files['file'])) {
$pretitle = str_replace('&','&amp;', $files['name']);
$n_path=$pretitle;
} else {
$pretitle = substr($path,-1)=='/'?substr($path,0,-1):$path;
$n_path=substr($pretitle,strrpos($pretitle,'/')+1);
$pretitle = substr($pretitle,1);
}
if (strrpos($path,'/')!=0) {
$p_path=substr($path,0,strrpos($path,'/'));
$p_path=substr($p_path,strrpos($p_path,'/')+1);
}
} else {
$pretitle = getconstStr('Home');
$n_path=$pretitle;
}
$n_path=str_replace('&amp;','&',$n_path);
$p_path=str_replace('&amp;','&',$p_path);
$pretitle = str_replace('%23','#',$pretitle);
$statusCode=200;
date_default_timezone_set(get_timezone($_COOKIE['timezone']));
@ob_start();
$theme = getConfig('theme');
if ( $theme=='' || !file_exists('theme/'.$theme) ) $theme = 'classic.php';
include 'theme/'.$theme;
$html = '<!--
github https://github.com/qkqpttgf/OneManager-php
-->' . ob_get_clean();
if ($_SERVER['Set-Cookie']!='') return output($html, $statusCode, [ 'Set-Cookie' => $_SERVER['Set-Cookie'], 'Content-Type' => 'text/html' ]);
return output($html,$statusCode);
}

396
function/heroku.php Normal file
View File

@ -0,0 +1,396 @@
<?php
function getpath()
{
$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
$_SERVER['base_path'] = path_format(substr($_SERVER['SCRIPT_NAME'], 0, -10) . '/');
$p = strpos($_SERVER['REQUEST_URI'],'?');
if ($p>0) $path = substr($_SERVER['REQUEST_URI'], 0, $p);
else $path = $_SERVER['REQUEST_URI'];
$path = path_format( substr($path, strlen($_SERVER['base_path'])) );
return $path;
//return spurlencode($path, '/');
}
function getGET()
{
$p = strpos($_SERVER['REQUEST_URI'],'?');
if ($p>0) {
$getstr = substr($_SERVER['REQUEST_URI'], $p+1);
$getstrarr = explode("&",$getstr);
foreach ($getstrarr as $getvalues) {
if ($getvalues != '') {
$pos = strpos($getvalues, "=");
//echo $pos;
if ($pos > 0) {
$getarry[urldecode(substr($getvalues, 0, $pos))] = urldecode(substr($getvalues, $pos + 1));
} else {
$getarry[urldecode($getvalues)] = true;
}
}
}
}
if (isset($getarry)) {
return $getarry;
} else {
return [];
}
}
function get_refresh_token()
{
global $constStr;
$url = path_format($_SERVER['PHP_SELF'] . '/');
if ($_GET['authorization_code'] && isset($_GET['code'])) {
$tmp = curl_request($_SERVER['oauth_url'] . 'token', 'client_id=' . $_SERVER['client_id'] .'&client_secret=' . $_SERVER['client_secret'] . '&grant_type=authorization_code&requested_token_use=on_behalf_of&redirect_uri=' . $_SERVER['redirect_uri'] .'&code=' . $_GET['code']);
if ($tmp['stat']==200) $ret = json_decode($tmp['body'], true);
if (isset($ret['refresh_token'])) {
$tmptoken = $ret['refresh_token'];
$str = '
refresh_token :<br>';
/*for ($i=1;strlen($tmptoken)>0;$i++) {
$t['t' . $i] = substr($tmptoken,0,128);
$str .= '
t' . $i . ':<textarea readonly style="width: 95%">' . $t['t' . $i] . '</textarea><br><br>';
$tmptoken=substr($tmptoken,128);
}
$str .= '
Add t1-t'.--$i.' to environments.*/
$str .= '
<textarea readonly style="width: 95%">' . $tmptoken . '</textarea><br><br>
Adding refresh_token to Config.
<script>
var texta=document.getElementsByTagName(\'textarea\');
for(i=0;i<texta.length;i++) {
texta[i].style.height = texta[i].scrollHeight + \'px\';
}
document.cookie=\'language=; path=/\';
</script>';
setConfig([ 'refresh_token' => $tmptoken ]);
savecache('access_token', $ret['access_token'], $ret['expires_in'] - 60);
$str .= '
<meta http-equiv="refresh" content="5;URL=' . $url . '">';
return message($str, getconstStr('WaitJumpIndex'));
}
return message('<pre>' . $tmp['body'] . '</pre>', $tmp['stat']);
//return message('<pre>' . json_encode($ret, JSON_PRETTY_PRINT) . '</pre>', 500);
}
if ($_GET['install3']) {
if (getConfig('Onedrive_ver')=='MS' || getConfig('Onedrive_ver')=='CN' || getConfig('Onedrive_ver')=='MSC') {
return message('
<a href="" id="a1">'.getconstStr('JumptoOffice').'</a>
<script>
url=location.protocol + "//" + location.host + "'.$url.'";
url="'. $_SERVER['oauth_url'] .'authorize?scope='. $_SERVER['scope'] .'&response_type=code&client_id='. $_SERVER['client_id'] .'&redirect_uri='. $_SERVER['redirect_uri'] . '&state=' .'"+encodeURIComponent(url);
document.getElementById(\'a1\').href=url;
//window.open(url,"_blank");
location.href = url;
</script>
', getconstStr('Wait').' 1s', 201);
}
}
if ($_GET['install2']) {
// echo $_POST['Onedrive_ver'];
if ($_POST['Onedrive_ver']=='MS' || $_POST['Onedrive_ver']=='CN' || $_POST['Onedrive_ver']=='MSC') {
$tmp['Onedrive_ver'] = $_POST['Onedrive_ver'];
if ($_POST['Onedrive_ver']=='MSC') {
$tmp['client_id'] = $_POST['client_id'];
$tmp['client_secret'] = $_POST['client_secret'];
}
$response = json_decode(setConfig($tmp)['body'], true);
$title = getconstStr('MayinEnv');
$html = getconstStr('Wait') . ' 3s<meta http-equiv="refresh" content="3;URL=' . $url . '?install3">';
if (isset($response['id'])&&isset($response['message'])) {
$html = $response['id'] . '<br>
' . $response['message'] . '<br><br>
function_name:' . $_SERVER['function_name'] . '<br>
<button onclick="location.href = location.href;">'.$constStr['Reflesh'][$constStr['language']].'</button>';
$title = 'Error';
}
return message($html, $title, 201);
}
}
if ($_GET['install1']) {
if ($_POST['admin']!='') {
$tmp['admin'] = $_POST['admin'];
$tmp['language'] = $_POST['language'];
$APIKey = getConfig('APIKey');
if ($APIKey=='') {
$APIKey = $_POST['APIKey'];
$tmp['APIKey'] = $APIKey;
}
$function_name = getConfig('function_name');
if ($function_name=='') {
$tmp1 = substr($_SERVER['HTTP_HOST'], 0, strrpos($_SERVER['HTTP_HOST'], '.'));
$maindomain = substr($tmp1, strrpos($tmp1, '.')+1);
if ($maindomain=='herokuapp') $function_name = substr($tmp1, 0, strrpos($tmp1, '.'));
else $function_name = 'visit from x.herokuapp.com';
$tmp['function_name'] = $function_name;
}
$response = json_decode(setHerokuConfig($tmp, $function_name, $APIKey)['body'], true);
if (isset($response['id'])&&isset($response['message'])) {
$html = $response['id'] . '<br>
' . $response['message'] . '<br><br>
function_name:' . $_SERVER['function_name'] . '<br>
<button onclick="location.href = location.href;">'.$constStr['Reflesh'][$constStr['language']].'</button>';
$title = 'Error';
} else {
if ($constStr['language']!='zh-cn') {
$linklang='en-us';
} else $linklang='zh-cn';
$ru = "https://developer.microsoft.com/".$linklang."/graph/quick-start?appID=_appId_&appName=_appName_&redirectUrl=".$_SERVER['redirect_uri']."&platform=option-php";
$deepLink = "/quickstart/graphIO?publicClientSupport=false&appName=OneManager&redirectUrl=".$_SERVER['redirect_uri']."&allowImplicitFlow=false&ru=".urlencode($ru);
$app_url = "https://apps.dev.microsoft.com/?deepLink=".urlencode($deepLink);
$html = '
<form action="?install2" method="post">
Onedrive_Ver<br>
<label><input type="radio" name="Onedrive_ver" value="MS" checked>MS: '.getconstStr('OndriveVerMS').'</label><br>
<label><input type="radio" name="Onedrive_ver" value="CN">CN: '.getconstStr('OndriveVerCN').'</label><br>
<label><input type="radio" name="Onedrive_ver" value="MSC" onclick="document.getElementById(\'secret\').style.display=\'\';">MSC: '.getconstStr('OndriveVerMSC').'
<div id="secret" style="display:none">
<a href="'.$app_url.'" target="_blank">'.getconstStr('GetSecretIDandKEY').'</a><br>
client_secret:<input type="text" name="client_secret"><br>
client_id(12345678-90ab-cdef-ghij-klmnopqrstuv):<input type="text" name="client_id"><br>
</div>
</label><br>
<input type="submit" value="'.getconstStr('Submit').'">
</form>';
$title = 'Install';
}
return message($html, $title, 201);
}
}
if ($_GET['install0']) {
$html .= '
<form action="?install1" method="post" onsubmit="return notnull(this);">
language:<br>';
foreach ($constStr['languages'] as $key1 => $value1) {
$html .= '
<label><input type="radio" name="language" value="'.$key1.'" '.($key1==$constStr['language']?'checked':'').' onclick="changelanguage(\''.$key1.'\')">'.$value1.'</label><br>';
}
if (getConfig('APIKey')=='') $html .= '
<a href="https://dashboard.heroku.com/account" target="_blank">'.getconstStr('Create').' API Key</a><br>
<label>API Key:<input name="APIKey" type="text" placeholder="" size=""></label><br>';
$html .= '
<label>admin:<input name="admin" type="password" placeholder="' . getconstStr('EnvironmentsDescription')['admin'] . '" size="' . strlen(getconstStr('EnvironmentsDescription')['admin']) . '"></label><br>';
$html .= '
<input type="submit" value="'.getconstStr('Submit').'">
</form>
<script>
function changelanguage(str)
{
document.cookie=\'language=\'+str+\'; path=/\';
location.href = location.href;
}
function notnull(t)
{
if (t.admin.value==\'\') {
alert(\'input admin\');
return false;
}';
if (getConfig('APIKey')=='') $html .= '
if (t.SecretId.value==\'\') {
alert(\'input SecretId\');
return false;
}
if (t.SecretKey.value==\'\') {
alert(\'input SecretKey\');
return false;
}';
$html .= '
return true;
}
</script>';
$title = getconstStr('SelectLanguage');
return message($html, $title, 201);
}
$html .= 'refresh_token not exist, <a href="?install0">click to install.</a>';
$title = 'Error';
return message($html, $title, 201);
}
function getConfig($str)
{
return getenv($str);
}
function array_value_isnot_null($arr)
{
return $arr!=='';
}
function setConfig($arr)
{
return setHerokuConfig($arr, getConfig('function_name'), getConfig('APIKey'));
}
function HerokuAPI($method, $url, $data = '', $apikey)
{
if ($method=='PATCH') {
$headers['Content-Type'] = 'application/json';
}
$headers['Authorization'] = 'Bearer ' . $apikey;
$headers['Accept'] = 'application/vnd.heroku+json; version=3';
//if (!isset($headers['Accept'])) $headers['Accept'] = '*/*';
//if (!isset($headers['Referer'])) $headers['Referer'] = $url;
$sendHeaders = array();
foreach ($headers as $headerName => $headerVal) {
$sendHeaders[] = $headerName . ': ' . $headerVal;
}
error_log($method . $url . $data . $apikey);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST,$method);
curl_setopt($ch, CURLOPT_POSTFIELDS,$data);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_HTTPHEADER, $sendHeaders);
$response['body'] = curl_exec($ch);
$response['stat'] = curl_getinfo($ch,CURLINFO_HTTP_CODE);
curl_close($ch);
error_log($response['stat'].'
'.$response['body'].'
');
return $response;
}
function getHerokuConfig($function_name, $apikey)
{
return HerokuAPI('GET', 'https://api.heroku.com/apps/' . $function_name . '/config-vars', '', $apikey);
}
function setHerokuConfig($env, $function_name, $apikey)
{
$data = json_encode($env);
return HerokuAPI('PATCH', 'https://api.heroku.com/apps/' . $function_name . '/config-vars', $data, $apikey);
}
function EnvOpt($function_name, $needUpdate = 0)
{
global $constStr;
$constEnv = [
//'admin',
'adminloginpage', 'domain_path', 'guestup_path', 'passfile',
//'private_path',
'public_path', 'sitename', 'language', 'theme'
];
asort($constEnv);
$html = '<title>OneManager '.getconstStr('Setup').'</title>';
/*if ($_POST['updateProgram']==getconstStr('updateProgram')) {
$response = json_decode(updataProgram($function_name, $Region, $namespace), true)['Response'];
if (isset($response['Error'])) {
$html = $response['Error']['Code'] . '<br>
' . $response['Error']['Message'] . '<br><br>
function_name:' . $_SERVER['function_name'] . '<br>
Region:' . $_SERVER['Region'] . '<br>
namespace:' . $namespace . '<br>
<button onclick="location.href = location.href;">'.getconstStr('Reflesh').'</button>';
$title = 'Error';
} else {
$html .= getconstStr('UpdateSuccess') . '<br>
<button onclick="location.href = location.href;">'.getconstStr('Reflesh').'</button>';
$title = getconstStr('Setup');
}
return message($html, $title);
}*/
if ($_POST['submit1']) {
foreach ($_POST as $k => $v) {
if (in_array($k, $constEnv)) {
//if (!(getConfig($k)==''&&$v==''))
$tmp[$k] = $v;
}
}
/*if ($tmp['domain_path']!='') {
$tmp1 = explode("|",$tmp['domain_path']);
$tmparr = [];
foreach ($tmp1 as $multidomain_paths){
$pos = strpos($multidomain_paths,":");
if ($pos>0) $tmparr[substr($multidomain_paths, 0, $pos)] = path_format(substr($multidomain_paths, $pos+1));
}
$tmp['domain_path'] = $tmparr;
}*/
$response = setConfig($tmp);
if (!$response) {
$html = $response . '<br>
<button onclick="location.href = location.href;">'.getconstStr('Reflesh').'</button>';
$title = 'Error';
} else {
$html .= '<script>location.href=location.href</script>';
}
}
if ($_GET['preview']) {
$preurl = $_SERVER['PHP_SELF'] . '?preview';
} else {
$preurl = path_format($_SERVER['PHP_SELF'] . '/');
}
$html .= '
<a href="'.$preurl.'">'.getconstStr('Back').'</a>&nbsp;&nbsp;&nbsp;
<a href="https://github.com/qkqpttgf/OneManager-php">Github</a><br>';
/*if ($needUpdate) {
$html .= '<pre>' . $_SERVER['github_version'] . '</pre>
<form action="" method="post">
<input type="submit" name="updateProgram" value="'.getconstStr('updateProgram').'">
</form>';
} else {
$html .= getconstStr('NotNeedUpdate');
}*/
$html .= '
<form action="" method="post">
<table border=1 width=100%>';
foreach ($constEnv as $key) {
if ($key=='language') {
$html .= '
<tr>
<td><label>' . $key . '</label></td>
<td width=100%>
<select name="' . $key .'">';
foreach ($constStr['languages'] as $key1 => $value1) {
$html .= '
<option value="'.$key1.'" '.($key1==getConfig($key)?'selected="selected"':'').'>'.$value1.'</option>';
}
$html .= '
</select>
</td>
</tr>';
} elseif ($key=='theme') {
$theme_arr = scandir('theme');
$html .= '
<tr>
<td><label>' . $key . '</label></td>
<td width=100%>
<select name="' . $key .'">';
foreach ($theme_arr as $v1) {
if ($v1!='.' && $v1!='..') $html .= '
<option value="'.$v1.'" '.($v1==getConfig($key)?'selected="selected"':'').'>'.$v1.'</option>';
}
$html .= '
</select>
</td>
</tr>';
} /*elseif ($key=='domain_path') {
$tmp = getConfig($key);
$domain_path = '';
foreach ($tmp as $k1 => $v1) {
$domain_path .= $k1 . ':' . $v1 . '|';
}
$domain_path = substr($domain_path, 0, -1);
$html .= '
<tr>
<td><label>' . $key . '</label></td>
<td width=100%><input type="text" name="' . $key .'" value="' . $domain_path . '" placeholder="' . getconstStr('EnvironmentsDescription')[$key] . '" style="width:100%"></td>
</tr>';
}*/ else $html .= '
<tr>
<td><label>' . $key . '</label></td>
<td width=100%><input type="text" name="' . $key .'" value="' . getConfig($key) . '" placeholder="' . getconstStr('EnvironmentsDescription')[$key] . '" style="width:100%"></td>
</tr>';
}
$html .= '</table>
<input type="submit" name="submit1" value="'.getconstStr('Setup').'">
</form>';
return message($html, getconstStr('Setup'));
}

397
function/normal.php Normal file
View File

@ -0,0 +1,397 @@
<?php
function getpath()
{
$_SERVER['base_path'] = path_format(substr($_SERVER['SCRIPT_NAME'], 0, -10) . '/');
$p = strpos($_SERVER['REQUEST_URI'],'?');
if ($p>0) $path = substr($_SERVER['REQUEST_URI'], 0, $p);
else $path = $_SERVER['REQUEST_URI'];
$path = path_format( substr($path, strlen($_SERVER['base_path'])) );
return $path;
//return spurlencode($path, '/');
}
function getGET()
{
$p = strpos($_SERVER['REQUEST_URI'],'?');
if ($p>0) {
$getstr = substr($_SERVER['REQUEST_URI'], $p+1);
$getstrarr = explode("&",$getstr);
foreach ($getstrarr as $getvalues) {
if ($getvalues != '') {
$pos = strpos($getvalues, "=");
//echo $pos;
if ($pos > 0) {
$getarry[urldecode(substr($getvalues, 0, $pos))] = urldecode(substr($getvalues, $pos + 1));
} else {
$getarry[urldecode($getvalues)] = true;
}
}
}
}
if (isset($getarry)) {
return $getarry;
} else {
return [];
}
}
function get_refresh_token()
{
global $constStr;
$url = path_format($_SERVER['PHP_SELF'] . '/');
if ($_GET['authorization_code'] && isset($_GET['code'])) {
$tmp = curl_request($_SERVER['oauth_url'] . 'token', 'client_id=' . $_SERVER['client_id'] .'&client_secret=' . $_SERVER['client_secret'] . '&grant_type=authorization_code&requested_token_use=on_behalf_of&redirect_uri=' . $_SERVER['redirect_uri'] .'&code=' . $_GET['code']);
if ($tmp['stat']==200) $ret = json_decode($tmp['body'], true);
if (isset($ret['refresh_token'])) {
$tmptoken = $ret['refresh_token'];
$str = '
refresh_token :<br>';
/*for ($i=1;strlen($tmptoken)>0;$i++) {
$t['t' . $i] = substr($tmptoken,0,128);
$str .= '
t' . $i . ':<textarea readonly style="width: 95%">' . $t['t' . $i] . '</textarea><br><br>';
$tmptoken=substr($tmptoken,128);
}
$str .= '
Add t1-t'.--$i.' to environments.*/
$str .= '
<textarea readonly style="width: 95%">' . $tmptoken . '</textarea><br><br>
Adding refresh_token to Config.
<script>
var texta=document.getElementsByTagName(\'textarea\');
for(i=0;i<texta.length;i++) {
texta[i].style.height = texta[i].scrollHeight + \'px\';
}
document.cookie=\'language=; path=/\';
</script>';
setConfig([ 'refresh_token' => $tmptoken ]);
savecache('access_token', $ret['access_token'], $ret['expires_in'] - 60);
$str .= '
<meta http-equiv="refresh" content="5;URL=' . $url . '">';
return message($str, getconstStr('WaitJumpIndex'));
}
return message('<pre>' . $tmp['body'] . '</pre>', $tmp['stat']);
//return message('<pre>' . json_encode($ret, JSON_PRETTY_PRINT) . '</pre>', 500);
}
if ($_GET['install3']) {
if (getConfig('Onedrive_ver')=='MS' || getConfig('Onedrive_ver')=='CN' || getConfig('Onedrive_ver')=='MSC') {
return message('
<a href="" id="a1">'.getconstStr('JumptoOffice').'</a>
<script>
url=location.protocol + "//" + location.host + "'.$url.'";
url="'. $_SERVER['oauth_url'] .'authorize?scope='. $_SERVER['scope'] .'&response_type=code&client_id='. $_SERVER['client_id'] .'&redirect_uri='. $_SERVER['redirect_uri'] . '&state=' .'"+encodeURIComponent(url);
document.getElementById(\'a1\').href=url;
//window.open(url,"_blank");
location.href = url;
</script>
', getconstStr('Wait').' 1s', 201);
}
}
if ($_GET['install2']) {
// echo $_POST['Onedrive_ver'];
if ($_POST['Onedrive_ver']=='MS' || $_POST['Onedrive_ver']=='CN' || $_POST['Onedrive_ver']=='MSC') {
$tmp['Onedrive_ver'] = $_POST['Onedrive_ver'];
if ($_POST['Onedrive_ver']=='MSC') {
$tmp['client_id'] = $_POST['client_id'];
$tmp['client_secret'] = $_POST['client_secret'];
}
$response = setConfig($tmp);
$title = getconstStr('MayinEnv');
$html = getconstStr('Wait') . ' 3s<meta http-equiv="refresh" content="3;URL=' . $url . '?install3">';
if (!$response) {
$html = $response . '<br>
Can not write config to file.<br>
<button onclick="location.href = location.href;">'.getconstStr('Reflesh').'</button>';
$title = 'Error';
}
return message($html, $title, 201);
}
}
if ($_GET['install1']) {
if ($_POST['admin']!='') {
$tmp['admin'] = $_POST['admin'];
$tmp['language'] = $_POST['language'];
$response = setConfig($tmp);
if ($response) {
if ($constStr['language']!='zh-cn') {
$linklang='en-us';
} else $linklang='zh-cn';
$ru = "https://developer.microsoft.com/".$linklang."/graph/quick-start?appID=_appId_&appName=_appName_&redirectUrl=".$_SERVER['redirect_uri']."&platform=option-php";
$deepLink = "/quickstart/graphIO?publicClientSupport=false&appName=OneManager&redirectUrl=".$_SERVER['redirect_uri']."&allowImplicitFlow=false&ru=".urlencode($ru);
$app_url = "https://apps.dev.microsoft.com/?deepLink=".urlencode($deepLink);
$html = '
<form action="?install2" method="post">
Onedrive_Ver<br>
<label><input type="radio" name="Onedrive_ver" value="MS" checked>MS: '.getconstStr('OndriveVerMS').'</label><br>
<label><input type="radio" name="Onedrive_ver" value="CN">CN: '.getconstStr('OndriveVerCN').'</label><br>
<label><input type="radio" name="Onedrive_ver" value="MSC" onclick="document.getElementById(\'secret\').style.display=\'\';">MSC: '.getconstStr('OndriveVerMSC').'
<div id="secret" style="display:none">
<a href="'.$app_url.'" target="_blank">'.getconstStr('GetSecretIDandKEY').'</a><br>
client_secret:<input type="text" name="client_secret"><br>
client_id(12345678-90ab-cdef-ghij-klmnopqrstuv):<input type="text" name="client_id"><br>
</div>
</label><br>
<input type="submit" value="'.getconstStr('Submit').'">
</form>';
$title = 'Install';
} else {
$html = $response . '<br>
Can not write config to file.<br>
<button onclick="location.href = location.href;">'.getconstStr('Reflesh').'</button>';
$title = 'Error';
}
return message($html, $title, 201);
}
}
if ($_GET['install0']) {
if (!ConfigWriteable()) {
$html .= 'Plase make sure the config.php is writeable.
run Writeable.sh.';
$title = 'Error';
return message($html, $title, 201);
}
if (!RewriteEngineOn()) {
$html .= 'Plase make sure the RewriteEngine is On.';
$title = 'Error';
return message($html, $title, 201);
}
$html .= '
<form action="?install1" method="post" onsubmit="return adminnotnull(this);">
language:<br>';
foreach ($constStr['languages'] as $key1 => $value1) {
$html .= '
<label><input type="radio" name="language" value="'.$key1.'" '.($key1==$constStr['language']?'checked':'').' onclick="changelanguage(\''.$key1.'\')">'.$value1.'</label><br>';
}
$html .= '<br>
<label>admin:<input name="admin" type="password" placeholder="' . getconstStr('EnvironmentsDescription')['admin'] . '" size="' . strlen(getconstStr('EnvironmentsDescription')['admin']) . '"></label><br>
<input type="submit" value="'.getconstStr('Submit').'">
</form>
<script>
function changelanguage(str)
{
document.cookie=\'language=\'+str+\'; path=/\';
location.href = location.href;
}
function adminnotnull(t)
{
if (t.admin.value==\'\') {
alert(\'input admin\');
return false;
}
return true;
}
</script>';
$title = getconstStr('SelectLanguage');
return message($html, $title, 201);
}
$html .= 'refresh_token not exist, <a href="?install0">click to install.</a>';
$title = 'Error';
return message($html, $title, 201);
}
function ConfigWriteable()
{
$t = md5( md5(time()).rand(1000,9999) );
setConfig([ 'tmp' => $t ]);
$tmp = getConfig('tmp');
setConfig([ 'tmp' => '' ]);
if ($tmp == $t) return true;
return false;
}
function RewriteEngineOn()
{
$http_type = ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')) ? 'https://' : 'http://';
$tmpurl=$http_type . $_SERVER['SERVER_NAME'] . path_format($_SERVER['base_path'] . '/config.php');
$tmp = curl_request($tmpurl);
if ($tmp['stat']==201) return true; //when install return 201, after installed return 404 or 200;
return false;
}
function getConfig($str)
{
include 'config.php';
//$s = file_get_contents('config.json');
if ($configs!='') {
$envs = json_decode($configs, true);
if (isset($envs[$str])) return $envs[$str];
}
return '';
/*
if (!class_exists('mydbreader')) {
class mydbreader extends SQLite3
{
function __construct()
{
$this->open( __DIR__ .'/.ht.db');
}
}
}
$db = new mydbreader();
if(!$db){
echo $db->lastErrorMsg();
} else {
//echo "Opened database successfully<br>\n";
$id=rand(1,309);
$sql="select * from config where id=".$str.";";
$ret = $db->query($sql);
if(!$ret){
echo $db->lastErrorMsg();
} else {
$row = $ret->fetchArray(SQLITE3_ASSOC);
$value1 = $row['value'];
}
$db->close();
}
return $value1;
*/
}
function array_value_isnot_null($arr)
{
return $arr!=='';
}
function setConfig($arr)
{
include 'config.php';
if ($configs!='') $envs = json_decode($configs, true);
foreach ($arr as $k1 => $v1) {
$envs[$k1] = $v1;
}
$envs = array_filter($envs, 'array_value_isnot_null');
ksort($envs);
//echo '<pre>'. json_encode($envs, JSON_PRETTY_PRINT).'</pre>';
$prestr = '<?php $configs = \'
';
$aftstr = '
\';';
return file_put_contents('config.php', $prestr . json_encode($envs, JSON_PRETTY_PRINT) . $aftstr);
}
function EnvOpt($function_name, $needUpdate = 0)
{
global $constStr;
$constEnv = [
//'admin',
'adminloginpage', 'domain_path', 'guestup_path', 'passfile',
//'private_path',
'public_path', 'sitename', 'language', 'theme'
];
asort($constEnv);
$html = '<title>OneManager '.getconstStr('Setup').'</title>';
/*if ($_POST['updateProgram']==getconstStr('updateProgram')) {
$response = json_decode(updataProgram($function_name, $Region, $namespace), true)['Response'];
if (isset($response['Error'])) {
$html = $response['Error']['Code'] . '<br>
' . $response['Error']['Message'] . '<br><br>
function_name:' . $_SERVER['function_name'] . '<br>
Region:' . $_SERVER['Region'] . '<br>
namespace:' . $namespace . '<br>
<button onclick="location.href = location.href;">'.getconstStr('Reflesh').'</button>';
$title = 'Error';
} else {
$html .= getconstStr('UpdateSuccess') . '<br>
<button onclick="location.href = location.href;">'.getconstStr('Reflesh').'</button>';
$title = getconstStr('Setup');
}
return message($html, $title);
}*/
if ($_POST['submit1']) {
foreach ($_POST as $k => $v) {
if (in_array($k, $constEnv)) {
//if (!(getConfig($k)==''&&$v==''))
$tmp[$k] = $v;
}
}
if ($tmp['domain_path']!='') {
$tmp1 = explode("|",$tmp['domain_path']);
$tmparr = [];
foreach ($tmp1 as $multidomain_paths){
$pos = strpos($multidomain_paths,":");
if ($pos>0) $tmparr[substr($multidomain_paths, 0, $pos)] = path_format(substr($multidomain_paths, $pos+1));
}
$tmp['domain_path'] = $tmparr;
}
$response = setConfig($tmp);
if (!$response) {
$html = $response . '<br>
<button onclick="location.href = location.href;">'.getconstStr('Reflesh').'</button>';
$title = 'Error';
} else {
$html .= '<script>location.href=location.href</script>';
}
}
if ($_GET['preview']) {
$preurl = $_SERVER['PHP_SELF'] . '?preview';
} else {
$preurl = path_format($_SERVER['PHP_SELF'] . '/');
}
$html .= '
<a href="'.$preurl.'">'.getconstStr('Back').'</a>&nbsp;&nbsp;&nbsp;
<a href="https://github.com/qkqpttgf/OneManager-php">Github</a><br>';
/*if ($needUpdate) {
$html .= '<pre>' . $_SERVER['github_version'] . '</pre>
<form action="" method="post">
<input type="submit" name="updateProgram" value="'.getconstStr('updateProgram').'">
</form>';
} else {
$html .= getconstStr('NotNeedUpdate');
}*/
$html .= '
<form action="" method="post">
<table border=1 width=100%>';
foreach ($constEnv as $key) {
if ($key=='language') {
$html .= '
<tr>
<td><label>' . $key . '</label></td>
<td width=100%>
<select name="' . $key .'">';
foreach ($constStr['languages'] as $key1 => $value1) {
$html .= '
<option value="'.$key1.'" '.($key1==getConfig($key)?'selected="selected"':'').'>'.$value1.'</option>';
}
$html .= '
</select>
</td>
</tr>';
} elseif ($key=='theme') {
$theme_arr = scandir('theme');
$html .= '
<tr>
<td><label>' . $key . '</label></td>
<td width=100%>
<select name="' . $key .'">';
foreach ($theme_arr as $v1) {
if ($v1!='.' && $v1!='..') $html .= '
<option value="'.$v1.'" '.($v1==getConfig($key)?'selected="selected"':'').'>'.$v1.'</option>';
}
$html .= '
</select>
</td>
</tr>';
} elseif ($key=='domain_path') {
$tmp = getConfig($key);
$domain_path = '';
foreach ($tmp as $k1 => $v1) {
$domain_path .= $k1 . ':' . $v1 . '|';
}
$domain_path = substr($domain_path, 0, -1);
$html .= '
<tr>
<td><label>' . $key . '</label></td>
<td width=100%><input type="text" name="' . $key .'" value="' . $domain_path . '" placeholder="' . getconstStr('EnvironmentsDescription')[$key] . '" style="width:100%"></td>
</tr>';
} else $html .= '
<tr>
<td><label>' . $key . '</label></td>
<td width=100%><input type="text" name="' . $key .'" value="' . getConfig($key) . '" placeholder="' . getconstStr('EnvironmentsDescription')[$key] . '" style="width:100%"></td>
</tr>';
}
$html .= '</table>
<input type="submit" name="submit1" value="'.getconstStr('Setup').'">
</form>';
return message($html, getconstStr('Setup'));
}

549
function/scf.php Normal file
View File

@ -0,0 +1,549 @@
<?php
function printInput($event, $context)
{
if (strlen(json_encode($event['body']))>500) $event['body']=substr($event['body'],0,strpos($event['body'],'base64')+30) . '...Too Long!...' . substr($event['body'],-50);
echo urldecode(json_encode($event, JSON_PRETTY_PRINT)) . '
' . urldecode(json_encode($context, JSON_PRETTY_PRINT)) . '
';
}
function GetGlobalVariable($event)
{
$_GET = $event['queryString'];
$postbody = explode("&",$event['body']);
foreach ($postbody as $postvalues) {
$pos = strpos($postvalues,"=");
$_POST[urldecode(substr($postvalues,0,$pos))]=urldecode(substr($postvalues,$pos+1));
}
$cookiebody = explode("; ",$event['headers']['cookie']);
foreach ($cookiebody as $cookievalues) {
$pos = strpos($cookievalues,"=");
$_COOKIE[urldecode(substr($cookievalues,0,$pos))]=urldecode(substr($cookievalues,$pos+1));
}
}
function GetPathSetting($event, $context)
{
$_SERVER['function_name'] = $context['function_name'];
$_SERVER['namespace'] = $context['namespace'];
$host_name = $event['headers']['host'];
$serviceId = $event['requestContext']['serviceId'];
$public_path = path_format(getenv('public_path'));
$private_path = path_format(getenv('private_path'));
$domain_path = getenv('domain_path');
$tmp_path='';
if ($domain_path!='') {
$tmp = explode("|",$domain_path);
foreach ($tmp as $multidomain_paths){
$pos = strpos($multidomain_paths,":");
$tmp_path = path_format(substr($multidomain_paths,$pos+1));
if (substr($multidomain_paths,0,$pos)==$host_name) $private_path=$tmp_path;
}
}
// public_path is not Parent Dir of private_path. public_path 不能是 private_path 的上级目录。
if ($tmp_path!='') if ($public_path == substr($tmp_path,0,strlen($public_path))) $public_path=$tmp_path;
if ($public_path == substr($private_path,0,strlen($public_path))) $public_path=$private_path;
if ( $serviceId === substr($host_name,0,strlen($serviceId)) ) {
$_SERVER['base_path'] = '/'.$event['requestContext']['stage'].'/'.$_SERVER['function_name'].'/';
$_SERVER['list_path'] = $public_path;
$_SERVER['Region'] = substr($host_name, strpos($host_name, '.')+1);
$_SERVER['Region'] = substr($_SERVER['Region'], 0, strpos($_SERVER['Region'], '.'));
$path = substr($event['path'], strlen('/'.$_SERVER['function_name'].'/'));
} else {
$_SERVER['base_path'] = $event['requestContext']['path'];
$_SERVER['list_path'] = $private_path;
$_SERVER['Region'] = getenv('Region');
$path = substr($event['path'], strlen($event['requestContext']['path']));
}
if (substr($path,-1)=='/') $path=substr($path,0,-1);
if (empty($_SERVER['list_path'])) {
$_SERVER['list_path'] = '/';
} else {
$_SERVER['list_path'] = spurlencode($_SERVER['list_path'],'/') ;
}
$_SERVER['is_guestup_path'] = is_guestup_path($path);
$_SERVER['PHP_SELF'] = path_format($_SERVER['base_path'] . $path);
$_SERVER['REMOTE_ADDR'] = $event['requestContext']['sourceIp'];
$_SERVER['ajax']=0;
if ($event['headers']['x-requested-with']=='XMLHttpRequest') {
$_SERVER['ajax']=1;
}
/*
$referer = $event['headers']['referer'];
$tmpurl = substr($referer,strpos($referer,'//')+2);
$refererhost = substr($tmpurl,0,strpos($tmpurl,'/'));
if ($refererhost==$host_name) {
// Guest only upload from this site. 仅游客上传用referer不对就空值无法上传
$_SERVER['current_url'] = substr($referer,0,strpos($referer,'//')) . '//' . $host_name.$_SERVER['PHP_SELF'];
} else {
$_SERVER['current_url'] = '';
}
*/
return $path;
}
function getConfig($str)
{
return getenv($str);
}
function array_value_isnot_null($arr)
{
return $arr!=='';
}
function setConfig($arr)
{
//$function_name, $Region, $Namespace, $SecretId, $SecretKey
$function_name = $_SERVER['function_name'];
$Region = $_SERVER['Region'];
$Namespace = $_SERVER['namespace'];
$SecretId = getConfig('SecretId');
$SecretKey = getConfig('SecretKey');
return updateEnvironment($arr, $function_name, $Region, $Namespace, $SecretId, $SecretKey);
}
function get_refresh_token()
{
global $constStr;
$url = path_format($_SERVER['PHP_SELF'] . '/');
if ($_GET['authorization_code'] && isset($_GET['code'])) {
$tmp = curl_request($_SERVER['oauth_url'] . 'token', 'client_id=' . $_SERVER['client_id'] .'&client_secret=' . $_SERVER['client_secret'] . '&grant_type=authorization_code&requested_token_use=on_behalf_of&redirect_uri=' . $_SERVER['redirect_uri'] .'&code=' . $_GET['code']);
if ($tmp['stat']==200) $ret = json_decode($tmp['body'], true);
if (isset($ret['refresh_token'])) {
$tmptoken = $ret['refresh_token'];
$str = '
refresh_token :<br>';
/*for ($i=1;strlen($tmptoken)>0;$i++) {
$t['t' . $i] = substr($tmptoken,0,128);
$str .= '
t' . $i . ':<textarea readonly style="width: 95%">' . $t['t' . $i] . '</textarea><br><br>';
$tmptoken=substr($tmptoken,128);
}
$str .= '
Add t1-t'.--$i.' to environments.*/
$str .= '
<textarea readonly style="width: 95%">' . $tmptoken . '</textarea><br><br>
Adding refresh_token to Config.
<script>
var texta=document.getElementsByTagName(\'textarea\');
for(i=0;i<texta.length;i++) {
texta[i].style.height = texta[i].scrollHeight + \'px\';
}
document.cookie=\'language=; path=/\';
</script>';
setConfig([ 'refresh_token' => $tmptoken ]);
savecache('access_token', $ret['access_token'], $ret['expires_in'] - 60);
$str .= '
<meta http-equiv="refresh" content="5;URL=' . $url . '">';
return message($str, getconstStr('WaitJumpIndex'));
}
return message('<pre>' . $tmp['body'] . '</pre>', $tmp['stat']);
//return message('<pre>' . json_encode($ret, JSON_PRETTY_PRINT) . '</pre>', 500);
}
if ($_GET['install3']) {
if (getConfig('Onedrive_ver')=='MS' || getConfig('Onedrive_ver')=='CN' || getConfig('Onedrive_ver')=='MSC') {
return message('
<a href="" id="a1">'.getconstStr('JumptoOffice').'</a>
<script>
url=location.protocol + "//" + location.host + "'.$url.'";
url="'. $_SERVER['oauth_url'] .'authorize?scope='. $_SERVER['scope'] .'&response_type=code&client_id='. $_SERVER['client_id'] .'&redirect_uri='. $_SERVER['redirect_uri'] . '&state=' .'"+encodeURIComponent(url);
document.getElementById(\'a1\').href=url;
//window.open(url,"_blank");
location.href = url;
</script>
', getconstStr('Wait').' 1s', 201);
}
}
if ($_GET['install2']) {
// echo $_POST['Onedrive_ver'];
if ($_POST['Onedrive_ver']=='MS' || $_POST['Onedrive_ver']=='CN' || $_POST['Onedrive_ver']=='MSC') {
$tmp['Onedrive_ver'] = $_POST['Onedrive_ver'];
if ($_POST['Onedrive_ver']=='MSC') {
$tmp['client_id'] = $_POST['client_id'];
$tmp['client_secret'] = $_POST['client_secret'];
}
$response = setConfig($tmp);
$title = getconstStr('MayinEnv');
$html = getconstStr('Wait') . ' 3s<meta http-equiv="refresh" content="3;URL=' . $url . '?install3">';
if (isset($response['Error'])) {
$html = $response['Error']['Code'] . '<br>
' . $response['Error']['Message'] . '<br><br>
function_name:' . $_SERVER['function_name'] . '<br>
Region:' . $_SERVER['Region'] . '<br>
namespace:' . $Namespace . '<br>
<button onclick="location.href = location.href;">'.getconstStr('Reflesh').'</button>';
$title = 'Error';
}
return message($html, $title, 201);
}
}
if ($_GET['install1']) {
if ($_POST['admin']!='') {
$tmp['admin'] = $_POST['admin'];
$tmp['language'] = $_POST['language'];
$SecretId = getConfig('SecretId');
if ($SecretId=='') {
$SecretId = $_POST['SecretId'];
$tmp['SecretId'] = $SecretId;
}
$SecretKey = getConfig('SecretKey');
if ($SecretKey=='') {
$SecretKey = $_POST['SecretKey'];
$tmp['SecretKey'] = $SecretKey;
}
echo SetbaseConfig($_SERVER['function_name'], $_SERVER['Region'], $_SERVER['namespace'], $SecretId, $SecretKey);
$response = updateEnvironment($tmp, $_SERVER['function_name'], $_SERVER['Region'], $_SERVER['namespace'], $SecretId, $SecretKey);
if (isset($response['Error'])) {
$html = $response['Error']['Code'] . '<br>
' . $response['Error']['Message'] . '<br><br>
function_name:' . $_SERVER['function_name'] . '<br>
Region:' . $_SERVER['Region'] . '<br>
namespace:' . $Namespace . '<br>
<button onclick="location.href = location.href;">'.getconstStr('Reflesh').'</button>';
$title = 'Error';
} else {
if ($constStr['language']!='zh-cn') {
$linklang='en-us';
} else $linklang='zh-cn';
$ru = "https://developer.microsoft.com/".$linklang."/graph/quick-start?appID=_appId_&appName=_appName_&redirectUrl=".$_SERVER['redirect_uri']."&platform=option-php";
$deepLink = "/quickstart/graphIO?publicClientSupport=false&appName=OneManager&redirectUrl=".$_SERVER['redirect_uri']."&allowImplicitFlow=false&ru=".urlencode($ru);
$app_url = "https://apps.dev.microsoft.com/?deepLink=".urlencode($deepLink);
$html = '
<form action="?install2" method="post">
Onedrive_Ver<br>
<label><input type="radio" name="Onedrive_ver" value="MS" checked>MS: '.getconstStr('OndriveVerMS').'</label><br>
<label><input type="radio" name="Onedrive_ver" value="CN">CN: '.getconstStr('OndriveVerCN').'</label><br>
<label><input type="radio" name="Onedrive_ver" value="MSC" onclick="document.getElementById(\'secret\').style.display=\'\';">MSC: '.getconstStr('OndriveVerMSC').'
<div id="secret" style="display:none">
<a href="'.$app_url.'" target="_blank">'.getconstStr('GetSecretIDandKEY').'</a><br>
client_secret:<input type="text" name="client_secret"><br>
client_id(12345678-90ab-cdef-ghij-klmnopqrstuv):<input type="text" name="client_id"><br>
</div>
</label><br>
<input type="submit" value="'.getconstStr('Submit').'">
</form>';
$title = 'Install';
}
return message($html, $title, 201);
}
}
if ($_GET['install0']) {
$html .= '
<form action="?install1" method="post" onsubmit="return notnull(this);">
language:<br>';
foreach ($constStr['languages'] as $key1 => $value1) {
$html .= '
<label><input type="radio" name="language" value="'.$key1.'" '.($key1==$constStr['language']?'checked':'').' onclick="changelanguage(\''.$key1.'\')">'.$value1.'</label><br>';
}
if (getConfig('SecretId')==''||getConfig('SecretKey')=='') $html .= '
<a href="https://console.cloud.tencent.com/cam/capi" target="_blank">'.getconstStr('Create').' SecretId & SecretKey</a><br>
<label>SecretId:<input name="SecretId" type="text" placeholder="" size=""></label><br>
<label>SecretKey:<input name="SecretKey" type="text" placeholder="" size=""></label><br>';
$html .= '
<label>admin:<input name="admin" type="password" placeholder="' . getconstStr('EnvironmentsDescription')['admin'] . '" size="' . strlen(getconstStr('EnvironmentsDescription')['admin']) . '"></label><br>';
$html .= '
<input type="submit" value="'.getconstStr('Submit').'">
</form>
<script>
function changelanguage(str)
{
document.cookie=\'language=\'+str+\'; path=/\';
location.href = location.href;
}
function notnull(t)
{
if (t.admin.value==\'\') {
alert(\'input admin\');
return false;
}';
if (getConfig('SecretId')==''||getConfig('SecretKey')=='') $html .= '
if (t.SecretId.value==\'\') {
alert(\'input SecretId\');
return false;
}
if (t.SecretKey.value==\'\') {
alert(\'input SecretKey\');
return false;
}';
$html .= '
return true;
}
</script>';
$title = getconstStr('SelectLanguage');
return message($html, $title, 201);
}
$html .= 'refresh_token not exist, <a href="?install0">click to install.</a>';
$title = 'Error';
return message($html, $title, 201);
}
function post2url($url, $data)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$response = curl_exec($ch);
curl_close($ch);
//echo $response;
return $response;
}
function ReorganizeDate($arr)
{
$str = '';
ksort($arr);
foreach ($arr as $k1 => $v1) {
$str .= '&' . $k1 . '=' . $v1;
}
$str = substr($str, 1); // remove first '&'. 去掉第一个&
return $str;
}
function getfunctioninfo($function_name, $Region, $Namespace, $SecretId, $SecretKey)
{
//$meth = 'GET';
$meth = 'POST';
$host = 'scf.tencentcloudapi.com';
$tmpdata['Action'] = 'GetFunction';
$tmpdata['FunctionName'] = $function_name;
$tmpdata['Namespace'] = $Namespace;
$tmpdata['Nonce'] = time();
$tmpdata['Region'] = $Region;
$tmpdata['SecretId'] = $SecretId;
$tmpdata['Timestamp'] = time();
$tmpdata['Token'] = '';
$tmpdata['Version'] = '2018-04-16';
$data = ReorganizeDate($tmpdata);
$signStr = base64_encode(hash_hmac('sha1', $meth.$host.'/?'.$data, $SecretKey, true));
//echo urlencode($signStr);
//return file_get_contents('https://'.$url.'&Signature='.urlencode($signStr));
return post2url('https://'.$host, $data.'&Signature='.urlencode($signStr));
}
function updateEnvironment($Envs, $function_name, $Region, $Namespace, $SecretId, $SecretKey)
{
//print_r($Envs);
//json_decode($a,true)['Response']['Environment']['Variables'][0]['Key']
$tmp = json_decode(getfunctioninfo($function_name, $Region, $Namespace, $SecretId, $SecretKey),true)['Response']['Environment']['Variables'];
foreach ($tmp as $tmp1) {
$tmp_env[$tmp1['Key']] = $tmp1['Value'];
}
foreach ($Envs as $key1 => $value1) {
$tmp_env[$key1] = $value1;
}
$tmp_env = array_filter($tmp_env, 'array_value_isnot_null'); // remove null. 清除空值
$tmp_env['Region'] = $Region;
ksort($tmp_env);
$i = 0;
foreach ($tmp_env as $key1 => $value1) {
$tmpdata['Environment.Variables.'.$i.'.Key'] = $key1;
$tmpdata['Environment.Variables.'.$i.'.Value'] = $value1;
$i++;
}
$meth = 'POST';
$host = 'scf.tencentcloudapi.com';
$tmpdata['Action'] = 'UpdateFunctionConfiguration';
$tmpdata['FunctionName'] = $function_name;
$tmpdata['Namespace'] = $Namespace;
$tmpdata['Nonce'] = time();
$tmpdata['Region'] = $Region;
$tmpdata['SecretId'] = $SecretId;
$tmpdata['Timestamp'] = time();
$tmpdata['Token'] = '';
$tmpdata['Version'] = '2018-04-16';
$data = ReorganizeDate($tmpdata);
$signStr = base64_encode(hash_hmac('sha1', $meth.$host.'/?'.$data, $SecretKey, true));
//echo urlencode($signStr);
return post2url('https://'.$host, $data.'&Signature='.urlencode($signStr));
}
function SetbaseConfig($function_name, $Region, $Namespace, $SecretId, $SecretKey)
{
$meth = 'POST';
$host = 'scf.tencentcloudapi.com';
$tmpdata['Action'] = 'UpdateFunctionConfiguration';
$tmpdata['FunctionName'] = $function_name;
$tmpdata['Description'] = 'Onedrive index in SCF. SCF上的Onedrive目录网站程序。';
$tmpdata['MemorySize'] = 128;
$tmpdata['Timeout'] = 30;
$tmpdata['Namespace'] = $Namespace;
$tmpdata['Nonce'] = time();
$tmpdata['Region'] = $Region;
$tmpdata['SecretId'] = $SecretId;
$tmpdata['Timestamp'] = time();
$tmpdata['Token'] = '';
$tmpdata['Version'] = '2018-04-16';
$data = ReorganizeDate($tmpdata);
$signStr = base64_encode(hash_hmac('sha1', $meth.$host.'/?'.$data, $SecretKey, true));
//echo urlencode($signStr);
return post2url('https://'.$host, $data.'&Signature='.urlencode($signStr));
}
function updateProgram($function_name, $Region, $Namespace, $SecretId, $SecretKey)
{
$meth = 'POST';
$host = 'scf.tencentcloudapi.com';
$tmpdata['Action'] = 'UpdateFunctionCode';
$tmpdata['Code.GitUrl'] = 'https://github.com/qkqpttgf/OneDrive_SCF';
$tmpdata['CodeSource'] = 'Git';
$tmpdata['FunctionName'] = $function_name;
$tmpdata['Handler'] = 'index.main_handler';
$tmpdata['Namespace'] = $Namespace;
$tmpdata['Nonce'] = time();
$tmpdata['Region'] = $Region;
$tmpdata['SecretId'] = $SecretId;
$tmpdata['Timestamp'] = time();
$tmpdata['Token'] = '';
$tmpdata['Version'] = '2018-04-16';
$data = ReorganizeDate($tmpdata);
$signStr = base64_encode(hash_hmac('sha1', $meth.$host.'/?'.$data, $SecretKey, true));
//echo urlencode($signStr);
return post2url('https://'.$host, $data.'&Signature='.urlencode($signStr));
}
function EnvOpt($function_name, $needUpdate = 0)
{
global $constStr;
$constEnv = [
//'admin',
'adminloginpage', 'domain_path', 'guestup_path', 'passfile',
//'private_path',
'public_path', 'sitename', 'language', 'theme'
];
asort($constEnv);
$html = '<title>OneManager '.getconstStr('Setup').'</title>';
if ($_POST['updateProgram']==getconstStr('updateProgram')) {
$response = json_decode(updateProgram($function_name, $Region, $namespace), true)['Response'];
if (isset($response['Error'])) {
$html = $response['Error']['Code'] . '<br>
' . $response['Error']['Message'] . '<br><br>
function_name:' . $_SERVER['function_name'] . '<br>
Region:' . $_SERVER['Region'] . '<br>
namespace:' . $namespace . '<br>
<button onclick="location.href = location.href;">'.getconstStr('Reflesh').'</button>';
$title = 'Error';
} else {
$html .= getconstStr('UpdateSuccess') . '<br>
<button onclick="location.href = location.href;">'.getconstStr('Reflesh').'</button>';
$title = getconstStr('Setup');
}
return message($html, $title);
}
if ($_POST['submit1']) {
foreach ($_POST as $k => $v) {
if (in_array($k, $constEnv)) {
//if (!(getConfig($k)==''&&$v==''))
$tmp[$k] = $v;
}
}
/*if ($tmp['domain_path']!='') {
$tmp1 = explode("|",$tmp['domain_path']);
$tmparr = [];
foreach ($tmp1 as $multidomain_paths){
$pos = strpos($multidomain_paths,":");
if ($pos>0) $tmparr[substr($multidomain_paths, 0, $pos)] = path_format(substr($multidomain_paths, $pos+1));
}
$tmp['domain_path'] = $tmparr;
}*/
$response = setConfig($tmp);
if (isset($response['Error'])) {
$html = $response['Error']['Code'] . '<br>
' . $response['Error']['Message'] . '<br><br>
function_name:' . $_SERVER['function_name'] . '<br>
Region:' . $_SERVER['Region'] . '<br>
namespace:' . $Namespace . '<br>
<button onclick="location.href = location.href;">'.getconstStr('Reflesh').'</button>';
$title = 'Error';
} else {
sleep(3);
$html .= '<script>location.href=location.href</script>';
$title = getconstStr('Setup');
}
return message($html, $title);
}
if ($_GET['preview']) {
$preurl = $_SERVER['PHP_SELF'] . '?preview';
} else {
$preurl = path_format($_SERVER['PHP_SELF'] . '/');
}
$html .= '
<a href="'.$preurl.'">'.getconstStr('Back').'</a>&nbsp;&nbsp;&nbsp;
<a href="https://github.com/qkqpttgf/OneManager-php">Github</a><br>';
if ($needUpdate) {
$html .= '<pre>' . $_SERVER['github_version'] . '</pre>
<form action="" method="post">
<input type="submit" name="updateProgram" value="'.getconstStr('updateProgram').'">
</form>';
} else {
$html .= getconstStr('NotNeedUpdate');
}
$html .= '
<form action="" method="post">
<table border=1 width=100%>';
foreach ($constEnv as $key) {
if ($key=='language') {
$html .= '
<tr>
<td><label>' . $key . '</label></td>
<td width=100%>
<select name="' . $key .'">';
foreach ($constStr['languages'] as $key1 => $value1) {
$html .= '
<option value="'.$key1.'" '.($key1==getConfig($key)?'selected="selected"':'').'>'.$value1.'</option>';
}
$html .= '
</select>
</td>
</tr>';
} elseif ($key=='theme') {
$theme_arr = scandir('theme');
$html .= '
<tr>
<td><label>' . $key . '</label></td>
<td width=100%>
<select name="' . $key .'">';
foreach ($theme_arr as $v1) {
if ($v1!='.' && $v1!='..') $html .= '
<option value="'.$v1.'" '.($v1==getConfig($key)?'selected="selected"':'').'>'.$v1.'</option>';
}
$html .= '
</select>
</td>
</tr>';
} /*elseif ($key=='domain_path') {
$tmp = getConfig($key);
$domain_path = '';
foreach ($tmp as $k1 => $v1) {
$domain_path .= $k1 . ':' . $v1 . '|';
}
$domain_path = substr($domain_path, 0, -1);
$html .= '
<tr>
<td><label>' . $key . '</label></td>
<td width=100%><input type="text" name="' . $key .'" value="' . $domain_path . '" placeholder="' . getconstStr('EnvironmentsDescription')[$key] . '" style="width:100%"></td>
</tr>';
}*/ else $html .= '
<tr>
<td><label>' . $key . '</label></td>
<td width=100%><input type="text" name="' . $key .'" value="' . getConfig($key) . '" placeholder="' . getconstStr('EnvironmentsDescription')[$key] . '" style="width:100%"></td>
</tr>';
}
$html .= '</table>
<input type="submit" name="submit1" value="'.getconstStr('Setup').'">
</form>';
return message($html, getconstStr('Setup'));
}

View File

@ -1,24 +1,52 @@
<?php <?php
include 'vendor/autoload.php';
include 'conststr.php'; include 'conststr.php';
include 'function/common.php';
echo '<pre>' . json_encode($_SERVER, JSON_PRETTY_PRINT) . '</pre>'; //echo '<pre>'. json_encode($_SERVER, JSON_PRETTY_PRINT).'</pre>';
if (!isset($_SERVER['REDIRECT_URL'])) $_SERVER['REDIRECT_URL'] = '/index.php'; if ($_SERVER['USER']==='qcloud') {
if ($_SERVER['REDIRECT_URL']=='') $_SERVER['REDIRECT_URL']='/'; include 'function/scf.php';
$path = $_SERVER['REDIRECT_URL']; } elseif ($_SERVER['HEROKU_APP_DIR']==='/app') {
include 'function/heroku.php';
$getstr = substr(urldecode($_SERVER['REQUEST_URI']), strlen(urldecode($_SERVER['REDIRECT_URL']))); $path = getpath();
while (substr($getstr,0,1)=='/' || substr($getstr,0,1)=='?') $getstr = substr($getstr,1); //echo 'path:'. $path;
$getstrarr = explode("&",$getstr); $_GET = getGET();
foreach ($getstrarr as $getvalues) if ($getvalues!='') { //echo '<pre>'. json_encode($_GET, JSON_PRETTY_PRINT).'</pre>';
$pos = strpos($getvalues,"="); $re = main($path);
//echo $pos; $sendHeaders = array();
if ($pos>0) { foreach ($re['headers'] as $headerName => $headerVal) {
$getarry[urldecode(substr($getvalues,0,$pos))] = urldecode(substr($getvalues,$pos+1)); header($headerName . ': ' . $headerVal, true);
} else $getarry[urldecode($getvalues)] = true;
} }
if (isset($getarry)) { http_response_code($re['statusCode']);
$_GET = $getarry; echo $re['body'];
} else $_GET = ''; } else {
include 'function/normal.php';
$path = getpath();
//echo 'path:'. $path;
$_GET = getGET();
//echo '<pre>'. json_encode($_GET, JSON_PRETTY_PRINT).'</pre>';
echo '<pre>' . json_encode($_GET, JSON_PRETTY_PRINT) . '</pre>'; $re = main($path);
$sendHeaders = array();
foreach ($re['headers'] as $headerName => $headerVal) {
header($headerName . ': ' . $headerVal, true);
}
http_response_code($re['statusCode']);
echo $re['body'];
}
function main_handler($event, $context)
{
$event = json_decode(json_encode($event), true);
$context = json_decode(json_encode($context), true);
printInput($event, $context);
unset($_POST);
unset($_GET);
unset($_COOKIE);
unset($_SERVER);
GetGlobalVariable($event);
echo '<pre>'. json_encode($_COOKIE, JSON_PRETTY_PRINT).'</pre>';
config_oauth();
$path = GetPathSetting($event, $context);
return main($path);
}

11
readme.md Normal file
View File

@ -0,0 +1,11 @@
# Deploy to SCF
https://cloud.tencent.com/product/scf
Install: https://service-pgxgvop2-1258064400.ap-hongkong.apigateway.myqcloud.com/test/abcdef/%E6%97%A0%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%87%BD%E6%95%B0SCF%E6%90%AD%E5%BB%BAOneDrive.mp4?preview
DEMO: https://service-pgxgvop2-1258064400.ap-hongkong.apigateway.myqcloud.com/test/abcdef/
# Deploy to heroku
https://heroku.com
Click the button [![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy) to Deploy a new app, or create an app then deploy by connect github.
DEMO: https://herooneindex.herokuapp.com/

2029
theme/1.php Normal file

File diff suppressed because one or more lines are too long

1134
theme/classic.php Normal file

File diff suppressed because it is too large Load Diff

7
vendor/autoload.php vendored Normal file
View File

@ -0,0 +1,7 @@
<?php
// autoload.php @generated by Composer
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInit95653bfe69a47d1c8f876456a9c468fd::getLoader();

445
vendor/composer/ClassLoader.php vendored Normal file
View File

@ -0,0 +1,445 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer\Autoload;
/**
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
*
* $loader = new \Composer\Autoload\ClassLoader();
*
* // register classes with namespaces
* $loader->add('Symfony\Component', __DIR__.'/component');
* $loader->add('Symfony', __DIR__.'/framework');
*
* // activate the autoloader
* $loader->register();
*
* // to enable searching the include path (eg. for PEAR packages)
* $loader->setUseIncludePath(true);
*
* In this example, if you try to use a class in the Symfony\Component
* namespace or one of its children (Symfony\Component\Console for instance),
* the autoloader will first look for the class under the component/
* directory, and it will then fallback to the framework/ directory if not
* found before giving up.
*
* This class is loosely based on the Symfony UniversalClassLoader.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Jordi Boggiano <j.boggiano@seld.be>
* @see http://www.php-fig.org/psr/psr-0/
* @see http://www.php-fig.org/psr/psr-4/
*/
class ClassLoader
{
// PSR-4
private $prefixLengthsPsr4 = array();
private $prefixDirsPsr4 = array();
private $fallbackDirsPsr4 = array();
// PSR-0
private $prefixesPsr0 = array();
private $fallbackDirsPsr0 = array();
private $useIncludePath = false;
private $classMap = array();
private $classMapAuthoritative = false;
private $missingClasses = array();
private $apcuPrefix;
public function getPrefixes()
{
if (!empty($this->prefixesPsr0)) {
return call_user_func_array('array_merge', $this->prefixesPsr0);
}
return array();
}
public function getPrefixesPsr4()
{
return $this->prefixDirsPsr4;
}
public function getFallbackDirs()
{
return $this->fallbackDirsPsr0;
}
public function getFallbackDirsPsr4()
{
return $this->fallbackDirsPsr4;
}
public function getClassMap()
{
return $this->classMap;
}
/**
* @param array $classMap Class to filename map
*/
public function addClassMap(array $classMap)
{
if ($this->classMap) {
$this->classMap = array_merge($this->classMap, $classMap);
} else {
$this->classMap = $classMap;
}
}
/**
* Registers a set of PSR-0 directories for a given prefix, either
* appending or prepending to the ones previously set for this prefix.
*
* @param string $prefix The prefix
* @param array|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
*/
public function add($prefix, $paths, $prepend = false)
{
if (!$prefix) {
if ($prepend) {
$this->fallbackDirsPsr0 = array_merge(
(array) $paths,
$this->fallbackDirsPsr0
);
} else {
$this->fallbackDirsPsr0 = array_merge(
$this->fallbackDirsPsr0,
(array) $paths
);
}
return;
}
$first = $prefix[0];
if (!isset($this->prefixesPsr0[$first][$prefix])) {
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
return;
}
if ($prepend) {
$this->prefixesPsr0[$first][$prefix] = array_merge(
(array) $paths,
$this->prefixesPsr0[$first][$prefix]
);
} else {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$this->prefixesPsr0[$first][$prefix],
(array) $paths
);
}
}
/**
* Registers a set of PSR-4 directories for a given namespace, either
* appending or prepending to the ones previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
*
* @throws \InvalidArgumentException
*/
public function addPsr4($prefix, $paths, $prepend = false)
{
if (!$prefix) {
// Register directories for the root namespace.
if ($prepend) {
$this->fallbackDirsPsr4 = array_merge(
(array) $paths,
$this->fallbackDirsPsr4
);
} else {
$this->fallbackDirsPsr4 = array_merge(
$this->fallbackDirsPsr4,
(array) $paths
);
}
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
// Register directories for a new namespace.
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
} elseif ($prepend) {
// Prepend directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
(array) $paths,
$this->prefixDirsPsr4[$prefix]
);
} else {
// Append directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$this->prefixDirsPsr4[$prefix],
(array) $paths
);
}
}
/**
* Registers a set of PSR-0 directories for a given prefix,
* replacing any others previously set for this prefix.
*
* @param string $prefix The prefix
* @param array|string $paths The PSR-0 base directories
*/
public function set($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr0 = (array) $paths;
} else {
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
}
}
/**
* Registers a set of PSR-4 directories for a given namespace,
* replacing any others previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-4 base directories
*
* @throws \InvalidArgumentException
*/
public function setPsr4($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr4 = (array) $paths;
} else {
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
}
}
/**
* Turns on searching the include path for class files.
*
* @param bool $useIncludePath
*/
public function setUseIncludePath($useIncludePath)
{
$this->useIncludePath = $useIncludePath;
}
/**
* Can be used to check if the autoloader uses the include path to check
* for classes.
*
* @return bool
*/
public function getUseIncludePath()
{
return $this->useIncludePath;
}
/**
* Turns off searching the prefix and fallback directories for classes
* that have not been registered with the class map.
*
* @param bool $classMapAuthoritative
*/
public function setClassMapAuthoritative($classMapAuthoritative)
{
$this->classMapAuthoritative = $classMapAuthoritative;
}
/**
* Should class lookup fail if not found in the current class map?
*
* @return bool
*/
public function isClassMapAuthoritative()
{
return $this->classMapAuthoritative;
}
/**
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
*
* @param string|null $apcuPrefix
*/
public function setApcuPrefix($apcuPrefix)
{
$this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
}
/**
* The APCu prefix in use, or null if APCu caching is not enabled.
*
* @return string|null
*/
public function getApcuPrefix()
{
return $this->apcuPrefix;
}
/**
* Registers this instance as an autoloader.
*
* @param bool $prepend Whether to prepend the autoloader or not
*/
public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
}
/**
* Unregisters this instance as an autoloader.
*/
public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
}
/**
* Loads the given class or interface.
*
* @param string $class The name of the class
* @return bool|null True if loaded, null otherwise
*/
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
includeFile($file);
return true;
}
}
/**
* Finds the path to the file where the class is defined.
*
* @param string $class The name of the class
*
* @return string|false The path if found, false otherwise
*/
public function findFile($class)
{
// class map lookup
if (isset($this->classMap[$class])) {
return $this->classMap[$class];
}
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
return false;
}
if (null !== $this->apcuPrefix) {
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
if ($hit) {
return $file;
}
}
$file = $this->findFileWithExtension($class, '.php');
// Search for Hack files if we are running on HHVM
if (false === $file && defined('HHVM_VERSION')) {
$file = $this->findFileWithExtension($class, '.hh');
}
if (null !== $this->apcuPrefix) {
apcu_add($this->apcuPrefix.$class, $file);
}
if (false === $file) {
// Remember that this class does not exist.
$this->missingClasses[$class] = true;
}
return $file;
}
private function findFileWithExtension($class, $ext)
{
// PSR-4 lookup
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
$first = $class[0];
if (isset($this->prefixLengthsPsr4[$first])) {
$subPath = $class;
while (false !== $lastPos = strrpos($subPath, '\\')) {
$subPath = substr($subPath, 0, $lastPos);
$search = $subPath . '\\';
if (isset($this->prefixDirsPsr4[$search])) {
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
foreach ($this->prefixDirsPsr4[$search] as $dir) {
if (file_exists($file = $dir . $pathEnd)) {
return $file;
}
}
}
}
}
// PSR-4 fallback dirs
foreach ($this->fallbackDirsPsr4 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
return $file;
}
}
// PSR-0 lookup
if (false !== $pos = strrpos($class, '\\')) {
// namespaced class name
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
} else {
// PEAR-like class name
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
}
if (isset($this->prefixesPsr0[$first])) {
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
if (0 === strpos($class, $prefix)) {
foreach ($dirs as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
}
}
}
// PSR-0 fallback dirs
foreach ($this->fallbackDirsPsr0 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
// PSR-0 include paths.
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
return $file;
}
return false;
}
}
/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*/
function includeFile($file)
{
include $file;
}

21
vendor/composer/LICENSE vendored Normal file
View File

@ -0,0 +1,21 @@
Copyright (c) Nils Adermann, Jordi Boggiano
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

9
vendor/composer/autoload_classmap.php vendored Normal file
View File

@ -0,0 +1,9 @@
<?php
// autoload_classmap.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
);

View File

@ -0,0 +1,9 @@
<?php
// autoload_namespaces.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
);

11
vendor/composer/autoload_psr4.php vendored Normal file
View File

@ -0,0 +1,11 @@
<?php
// autoload_psr4.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'Doctrine\\Common\\Cache\\' => array($vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache'),
'App\\' => array($baseDir . '/app'),
);

52
vendor/composer/autoload_real.php vendored Normal file
View File

@ -0,0 +1,52 @@
<?php
// autoload_real.php @generated by Composer
class ComposerAutoloaderInit95653bfe69a47d1c8f876456a9c468fd
{
private static $loader;
public static function loadClassLoader($class)
{
if ('Composer\Autoload\ClassLoader' === $class) {
require __DIR__ . '/ClassLoader.php';
}
}
public static function getLoader()
{
if (null !== self::$loader) {
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInit95653bfe69a47d1c8f876456a9c468fd', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array('ComposerAutoloaderInit95653bfe69a47d1c8f876456a9c468fd', 'loadClassLoader'));
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
if ($useStaticLoader) {
require_once __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit95653bfe69a47d1c8f876456a9c468fd::getInitializer($loader));
} else {
$map = require __DIR__ . '/autoload_namespaces.php';
foreach ($map as $namespace => $path) {
$loader->set($namespace, $path);
}
$map = require __DIR__ . '/autoload_psr4.php';
foreach ($map as $namespace => $path) {
$loader->setPsr4($namespace, $path);
}
$classMap = require __DIR__ . '/autoload_classmap.php';
if ($classMap) {
$loader->addClassMap($classMap);
}
}
$loader->register(true);
return $loader;
}
}

39
vendor/composer/autoload_static.php vendored Normal file
View File

@ -0,0 +1,39 @@
<?php
// autoload_static.php @generated by Composer
namespace Composer\Autoload;
class ComposerStaticInit95653bfe69a47d1c8f876456a9c468fd
{
public static $prefixLengthsPsr4 = array (
'D' =>
array (
'Doctrine\\Common\\Cache\\' => 22,
),
'A' =>
array (
'App\\' => 4,
),
);
public static $prefixDirsPsr4 = array (
'Doctrine\\Common\\Cache\\' =>
array (
0 => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache',
),
'App\\' =>
array (
0 => __DIR__ . '/../..' . '/app',
),
);
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInit95653bfe69a47d1c8f876456a9c468fd::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit95653bfe69a47d1c8f876456a9c468fd::$prefixDirsPsr4;
}, null, ClassLoader::class);
}
}

80
vendor/composer/installed.json vendored Normal file
View File

@ -0,0 +1,80 @@
[
{
"name": "doctrine/cache",
"version": "v1.6.2",
"version_normalized": "1.6.2.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/cache.git",
"reference": "eb152c5100571c7a45470ff2a35095ab3f3b900b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/cache/zipball/eb152c5100571c7a45470ff2a35095ab3f3b900b",
"reference": "eb152c5100571c7a45470ff2a35095ab3f3b900b",
"shasum": "",
"mirrors": [
{
"url": "https://dl.laravel-china.org/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": "~5.5|~7.0"
},
"conflict": {
"doctrine/common": ">2.2,<2.4"
},
"require-dev": {
"phpunit/phpunit": "~4.8|~5.0",
"predis/predis": "~1.0",
"satooshi/php-coveralls": "~0.6"
},
"time": "2017-07-22T12:49:21+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.6.x-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
},
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com"
}
],
"description": "Caching library offering an object-oriented API for many cache backends",
"homepage": "http://www.doctrine-project.org",
"keywords": [
"cache",
"caching"
]
}
]

View File

@ -0,0 +1,118 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
/**
* APC cache provider.
*
* @link www.doctrine-project.org
* @deprecated since version 1.6, use ApcuCache instead
* @since 2.0
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
* @author David Abdemoulaie <dave@hobodave.com>
*/
class ApcCache extends CacheProvider
{
/**
* {@inheritdoc}
*/
protected function doFetch($id)
{
return apc_fetch($id);
}
/**
* {@inheritdoc}
*/
protected function doContains($id)
{
return apc_exists($id);
}
/**
* {@inheritdoc}
*/
protected function doSave($id, $data, $lifeTime = 0)
{
return apc_store($id, $data, $lifeTime);
}
/**
* {@inheritdoc}
*/
protected function doDelete($id)
{
// apc_delete returns false if the id does not exist
return apc_delete($id) || ! apc_exists($id);
}
/**
* {@inheritdoc}
*/
protected function doFlush()
{
return apc_clear_cache() && apc_clear_cache('user');
}
/**
* {@inheritdoc}
*/
protected function doFetchMultiple(array $keys)
{
return apc_fetch($keys) ?: [];
}
/**
* {@inheritdoc}
*/
protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
{
$result = apc_store($keysAndValues, null, $lifetime);
return empty($result);
}
/**
* {@inheritdoc}
*/
protected function doGetStats()
{
$info = apc_cache_info('', true);
$sma = apc_sma_info();
// @TODO - Temporary fix @see https://github.com/krakjoe/apcu/pull/42
if (PHP_VERSION_ID >= 50500) {
$info['num_hits'] = isset($info['num_hits']) ? $info['num_hits'] : $info['nhits'];
$info['num_misses'] = isset($info['num_misses']) ? $info['num_misses'] : $info['nmisses'];
$info['start_time'] = isset($info['start_time']) ? $info['start_time'] : $info['stime'];
}
return array(
Cache::STATS_HITS => $info['num_hits'],
Cache::STATS_MISSES => $info['num_misses'],
Cache::STATS_UPTIME => $info['start_time'],
Cache::STATS_MEMORY_USAGE => $info['mem_size'],
Cache::STATS_MEMORY_AVAILABLE => $sma['avail_mem'],
);
}
}

View File

@ -0,0 +1,106 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
/**
* APCu cache provider.
*
* @link www.doctrine-project.org
* @since 1.6
* @author Kévin Dunglas <dunglas@gmail.com>
*/
class ApcuCache extends CacheProvider
{
/**
* {@inheritdoc}
*/
protected function doFetch($id)
{
return apcu_fetch($id);
}
/**
* {@inheritdoc}
*/
protected function doContains($id)
{
return apcu_exists($id);
}
/**
* {@inheritdoc}
*/
protected function doSave($id, $data, $lifeTime = 0)
{
return apcu_store($id, $data, $lifeTime);
}
/**
* {@inheritdoc}
*/
protected function doDelete($id)
{
// apcu_delete returns false if the id does not exist
return apcu_delete($id) || ! apcu_exists($id);
}
/**
* {@inheritdoc}
*/
protected function doFlush()
{
return apcu_clear_cache();
}
/**
* {@inheritdoc}
*/
protected function doFetchMultiple(array $keys)
{
return apcu_fetch($keys) ?: [];
}
/**
* {@inheritdoc}
*/
protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
{
$result = apcu_store($keysAndValues, null, $lifetime);
return empty($result);
}
/**
* {@inheritdoc}
*/
protected function doGetStats()
{
$info = apcu_cache_info(true);
$sma = apcu_sma_info();
return array(
Cache::STATS_HITS => $info['num_hits'],
Cache::STATS_MISSES => $info['num_misses'],
Cache::STATS_UPTIME => $info['start_time'],
Cache::STATS_MEMORY_USAGE => $info['mem_size'],
Cache::STATS_MEMORY_AVAILABLE => $sma['avail_mem'],
);
}
}

View File

@ -0,0 +1,142 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
/**
* Array cache driver.
*
* @link www.doctrine-project.org
* @since 2.0
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
* @author David Abdemoulaie <dave@hobodave.com>
*/
class ArrayCache extends CacheProvider
{
/**
* @var array[] $data each element being a tuple of [$data, $expiration], where the expiration is int|bool
*/
private $data = [];
/**
* @var int
*/
private $hitsCount = 0;
/**
* @var int
*/
private $missesCount = 0;
/**
* @var int
*/
private $upTime;
/**
* {@inheritdoc}
*/
public function __construct()
{
$this->upTime = time();
}
/**
* {@inheritdoc}
*/
protected function doFetch($id)
{
if (! $this->doContains($id)) {
$this->missesCount += 1;
return false;
}
$this->hitsCount += 1;
return $this->data[$id][0];
}
/**
* {@inheritdoc}
*/
protected function doContains($id)
{
if (! isset($this->data[$id])) {
return false;
}
$expiration = $this->data[$id][1];
if ($expiration && $expiration < time()) {
$this->doDelete($id);
return false;
}
return true;
}
/**
* {@inheritdoc}
*/
protected function doSave($id, $data, $lifeTime = 0)
{
$this->data[$id] = [$data, $lifeTime ? time() + $lifeTime : false];
return true;
}
/**
* {@inheritdoc}
*/
protected function doDelete($id)
{
unset($this->data[$id]);
return true;
}
/**
* {@inheritdoc}
*/
protected function doFlush()
{
$this->data = [];
return true;
}
/**
* {@inheritdoc}
*/
protected function doGetStats()
{
return [
Cache::STATS_HITS => $this->hitsCount,
Cache::STATS_MISSES => $this->missesCount,
Cache::STATS_UPTIME => $this->upTime,
Cache::STATS_MEMORY_USAGE => null,
Cache::STATS_MEMORY_AVAILABLE => null,
];
}
}

View File

@ -0,0 +1,116 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
/**
* Interface for cache drivers.
*
* @link www.doctrine-project.org
* @since 2.0
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
* @author Kévin Dunglas <dunglas@gmail.com>
*/
interface Cache
{
const STATS_HITS = 'hits';
const STATS_MISSES = 'misses';
const STATS_UPTIME = 'uptime';
const STATS_MEMORY_USAGE = 'memory_usage';
const STATS_MEMORY_AVAILABLE = 'memory_available';
/**
* Only for backward compatibility (may be removed in next major release)
*
* @deprecated
*/
const STATS_MEMORY_AVAILIABLE = 'memory_available';
/**
* Fetches an entry from the cache.
*
* @param string $id The id of the cache entry to fetch.
*
* @return mixed The cached data or FALSE, if no cache entry exists for the given id.
*/
public function fetch($id);
/**
* Tests if an entry exists in the cache.
*
* @param string $id The cache id of the entry to check for.
*
* @return bool TRUE if a cache entry exists for the given cache id, FALSE otherwise.
*/
public function contains($id);
/**
* Puts data into the cache.
*
* If a cache entry with the given id already exists, its data will be replaced.
*
* @param string $id The cache id.
* @param mixed $data The cache entry/data.
* @param int $lifeTime The lifetime in number of seconds for this cache entry.
* If zero (the default), the entry never expires (although it may be deleted from the cache
* to make place for other entries).
*
* @return bool TRUE if the entry was successfully stored in the cache, FALSE otherwise.
*/
public function save($id, $data, $lifeTime = 0);
/**
* Deletes a cache entry.
*
* @param string $id The cache id.
*
* @return bool TRUE if the cache entry was successfully deleted, FALSE otherwise.
* Deleting a non-existing entry is considered successful.
*/
public function delete($id);
/**
* Retrieves cached information from the data store.
*
* The server's statistics array has the following values:
*
* - <b>hits</b>
* Number of keys that have been requested and found present.
*
* - <b>misses</b>
* Number of items that have been requested and not found.
*
* - <b>uptime</b>
* Time that the server is running.
*
* - <b>memory_usage</b>
* Memory used by this server to store items.
*
* - <b>memory_available</b>
* Memory allowed to use for storage.
*
* @since 2.2
*
* @return array|null An associative array with server's statistics if available, NULL otherwise.
*/
public function getStats();
}

View File

@ -0,0 +1,312 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
/**
* Base class for cache provider implementations.
*
* @since 2.2
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
*/
abstract class CacheProvider implements Cache, FlushableCache, ClearableCache, MultiGetCache, MultiPutCache
{
const DOCTRINE_NAMESPACE_CACHEKEY = 'DoctrineNamespaceCacheKey[%s]';
/**
* The namespace to prefix all cache ids with.
*
* @var string
*/
private $namespace = '';
/**
* The namespace version.
*
* @var integer|null
*/
private $namespaceVersion;
/**
* Sets the namespace to prefix all cache ids with.
*
* @param string $namespace
*
* @return void
*/
public function setNamespace($namespace)
{
$this->namespace = (string) $namespace;
$this->namespaceVersion = null;
}
/**
* Retrieves the namespace that prefixes all cache ids.
*
* @return string
*/
public function getNamespace()
{
return $this->namespace;
}
/**
* {@inheritdoc}
*/
public function fetch($id)
{
return $this->doFetch($this->getNamespacedId($id));
}
/**
* {@inheritdoc}
*/
public function fetchMultiple(array $keys)
{
if (empty($keys)) {
return array();
}
// note: the array_combine() is in place to keep an association between our $keys and the $namespacedKeys
$namespacedKeys = array_combine($keys, array_map(array($this, 'getNamespacedId'), $keys));
$items = $this->doFetchMultiple($namespacedKeys);
$foundItems = array();
// no internal array function supports this sort of mapping: needs to be iterative
// this filters and combines keys in one pass
foreach ($namespacedKeys as $requestedKey => $namespacedKey) {
if (isset($items[$namespacedKey]) || array_key_exists($namespacedKey, $items)) {
$foundItems[$requestedKey] = $items[$namespacedKey];
}
}
return $foundItems;
}
/**
* {@inheritdoc}
*/
public function saveMultiple(array $keysAndValues, $lifetime = 0)
{
$namespacedKeysAndValues = array();
foreach ($keysAndValues as $key => $value) {
$namespacedKeysAndValues[$this->getNamespacedId($key)] = $value;
}
return $this->doSaveMultiple($namespacedKeysAndValues, $lifetime);
}
/**
* {@inheritdoc}
*/
public function contains($id)
{
return $this->doContains($this->getNamespacedId($id));
}
/**
* {@inheritdoc}
*/
public function save($id, $data, $lifeTime = 0)
{
return $this->doSave($this->getNamespacedId($id), $data, $lifeTime);
}
/**
* {@inheritdoc}
*/
public function delete($id)
{
return $this->doDelete($this->getNamespacedId($id));
}
/**
* {@inheritdoc}
*/
public function getStats()
{
return $this->doGetStats();
}
/**
* {@inheritDoc}
*/
public function flushAll()
{
return $this->doFlush();
}
/**
* {@inheritDoc}
*/
public function deleteAll()
{
$namespaceCacheKey = $this->getNamespaceCacheKey();
$namespaceVersion = $this->getNamespaceVersion() + 1;
if ($this->doSave($namespaceCacheKey, $namespaceVersion)) {
$this->namespaceVersion = $namespaceVersion;
return true;
}
return false;
}
/**
* Prefixes the passed id with the configured namespace value.
*
* @param string $id The id to namespace.
*
* @return string The namespaced id.
*/
private function getNamespacedId($id)
{
$namespaceVersion = $this->getNamespaceVersion();
return sprintf('%s[%s][%s]', $this->namespace, $id, $namespaceVersion);
}
/**
* Returns the namespace cache key.
*
* @return string
*/
private function getNamespaceCacheKey()
{
return sprintf(self::DOCTRINE_NAMESPACE_CACHEKEY, $this->namespace);
}
/**
* Returns the namespace version.
*
* @return integer
*/
private function getNamespaceVersion()
{
if (null !== $this->namespaceVersion) {
return $this->namespaceVersion;
}
$namespaceCacheKey = $this->getNamespaceCacheKey();
$this->namespaceVersion = $this->doFetch($namespaceCacheKey) ?: 1;
return $this->namespaceVersion;
}
/**
* Default implementation of doFetchMultiple. Each driver that supports multi-get should owerwrite it.
*
* @param array $keys Array of keys to retrieve from cache
* @return array Array of values retrieved for the given keys.
*/
protected function doFetchMultiple(array $keys)
{
$returnValues = array();
foreach ($keys as $key) {
if (false !== ($item = $this->doFetch($key)) || $this->doContains($key)) {
$returnValues[$key] = $item;
}
}
return $returnValues;
}
/**
* Fetches an entry from the cache.
*
* @param string $id The id of the cache entry to fetch.
*
* @return mixed|false The cached data or FALSE, if no cache entry exists for the given id.
*/
abstract protected function doFetch($id);
/**
* Tests if an entry exists in the cache.
*
* @param string $id The cache id of the entry to check for.
*
* @return bool TRUE if a cache entry exists for the given cache id, FALSE otherwise.
*/
abstract protected function doContains($id);
/**
* Default implementation of doSaveMultiple. Each driver that supports multi-put should override it.
*
* @param array $keysAndValues Array of keys and values to save in cache
* @param int $lifetime The lifetime. If != 0, sets a specific lifetime for these
* cache entries (0 => infinite lifeTime).
*
* @return bool TRUE if the operation was successful, FALSE if it wasn't.
*/
protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
{
$success = true;
foreach ($keysAndValues as $key => $value) {
if (!$this->doSave($key, $value, $lifetime)) {
$success = false;
}
}
return $success;
}
/**
* Puts data into the cache.
*
* @param string $id The cache id.
* @param string $data The cache entry/data.
* @param int $lifeTime The lifetime. If != 0, sets a specific lifetime for this
* cache entry (0 => infinite lifeTime).
*
* @return bool TRUE if the entry was successfully stored in the cache, FALSE otherwise.
*/
abstract protected function doSave($id, $data, $lifeTime = 0);
/**
* Deletes a cache entry.
*
* @param string $id The cache id.
*
* @return bool TRUE if the cache entry was successfully deleted, FALSE otherwise.
*/
abstract protected function doDelete($id);
/**
* Flushes all cache entries.
*
* @return bool TRUE if the cache entries were successfully flushed, FALSE otherwise.
*/
abstract protected function doFlush();
/**
* Retrieves cached information from the data store.
*
* @since 2.2
*
* @return array|null An associative array with server's statistics if available, NULL otherwise.
*/
abstract protected function doGetStats();
}

View File

@ -0,0 +1,147 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
/**
* Cache provider that allows to easily chain multiple cache providers
*
* @author Michaël Gallego <mic.gallego@gmail.com>
*/
class ChainCache extends CacheProvider
{
/**
* @var CacheProvider[]
*/
private $cacheProviders = array();
/**
* Constructor
*
* @param CacheProvider[] $cacheProviders
*/
public function __construct($cacheProviders = array())
{
$this->cacheProviders = $cacheProviders;
}
/**
* {@inheritDoc}
*/
public function setNamespace($namespace)
{
parent::setNamespace($namespace);
foreach ($this->cacheProviders as $cacheProvider) {
$cacheProvider->setNamespace($namespace);
}
}
/**
* {@inheritDoc}
*/
protected function doFetch($id)
{
foreach ($this->cacheProviders as $key => $cacheProvider) {
if ($cacheProvider->doContains($id)) {
$value = $cacheProvider->doFetch($id);
// We populate all the previous cache layers (that are assumed to be faster)
for ($subKey = $key - 1 ; $subKey >= 0 ; $subKey--) {
$this->cacheProviders[$subKey]->doSave($id, $value);
}
return $value;
}
}
return false;
}
/**
* {@inheritDoc}
*/
protected function doContains($id)
{
foreach ($this->cacheProviders as $cacheProvider) {
if ($cacheProvider->doContains($id)) {
return true;
}
}
return false;
}
/**
* {@inheritDoc}
*/
protected function doSave($id, $data, $lifeTime = 0)
{
$stored = true;
foreach ($this->cacheProviders as $cacheProvider) {
$stored = $cacheProvider->doSave($id, $data, $lifeTime) && $stored;
}
return $stored;
}
/**
* {@inheritDoc}
*/
protected function doDelete($id)
{
$deleted = true;
foreach ($this->cacheProviders as $cacheProvider) {
$deleted = $cacheProvider->doDelete($id) && $deleted;
}
return $deleted;
}
/**
* {@inheritDoc}
*/
protected function doFlush()
{
$flushed = true;
foreach ($this->cacheProviders as $cacheProvider) {
$flushed = $cacheProvider->doFlush() && $flushed;
}
return $flushed;
}
/**
* {@inheritDoc}
*/
protected function doGetStats()
{
// We return all the stats from all adapters
$stats = array();
foreach ($this->cacheProviders as $cacheProvider) {
$stats[] = $cacheProvider->doGetStats();
}
return $stats;
}
}

View File

@ -0,0 +1,40 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
/**
* Interface for cache that can be flushed.
*
* Intended to be used for partial clearing of a cache namespace. For a more
* global "flushing", see {@see FlushableCache}.
*
* @link www.doctrine-project.org
* @since 1.4
* @author Adirelle <adirelle@gmail.com>
*/
interface ClearableCache
{
/**
* Deletes all cache entries in the current cache namespace.
*
* @return bool TRUE if the cache entries were successfully deleted, FALSE otherwise.
*/
public function deleteAll();
}

View File

@ -0,0 +1,121 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
use \Couchbase;
/**
* Couchbase cache provider.
*
* @link www.doctrine-project.org
* @since 2.4
* @author Michael Nitschinger <michael@nitschinger.at>
*/
class CouchbaseCache extends CacheProvider
{
/**
* @var Couchbase|null
*/
private $couchbase;
/**
* Sets the Couchbase instance to use.
*
* @param Couchbase $couchbase
*
* @return void
*/
public function setCouchbase(Couchbase $couchbase)
{
$this->couchbase = $couchbase;
}
/**
* Gets the Couchbase instance used by the cache.
*
* @return Couchbase|null
*/
public function getCouchbase()
{
return $this->couchbase;
}
/**
* {@inheritdoc}
*/
protected function doFetch($id)
{
return $this->couchbase->get($id) ?: false;
}
/**
* {@inheritdoc}
*/
protected function doContains($id)
{
return (null !== $this->couchbase->get($id));
}
/**
* {@inheritdoc}
*/
protected function doSave($id, $data, $lifeTime = 0)
{
if ($lifeTime > 30 * 24 * 3600) {
$lifeTime = time() + $lifeTime;
}
return $this->couchbase->set($id, $data, (int) $lifeTime);
}
/**
* {@inheritdoc}
*/
protected function doDelete($id)
{
return $this->couchbase->delete($id);
}
/**
* {@inheritdoc}
*/
protected function doFlush()
{
return $this->couchbase->flush();
}
/**
* {@inheritdoc}
*/
protected function doGetStats()
{
$stats = $this->couchbase->getStats();
$servers = $this->couchbase->getServers();
$server = explode(":", $servers[0]);
$key = $server[0] . ":" . "11210";
$stats = $stats[$key];
return array(
Cache::STATS_HITS => $stats['get_hits'],
Cache::STATS_MISSES => $stats['get_misses'],
Cache::STATS_UPTIME => $stats['uptime'],
Cache::STATS_MEMORY_USAGE => $stats['bytes'],
Cache::STATS_MEMORY_AVAILABLE => $stats['limit_maxbytes'],
);
}
}

View File

@ -0,0 +1,286 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
/**
* Base file cache driver.
*
* @since 2.3
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
* @author Tobias Schultze <http://tobion.de>
*/
abstract class FileCache extends CacheProvider
{
/**
* The cache directory.
*
* @var string
*/
protected $directory;
/**
* The cache file extension.
*
* @var string
*/
private $extension;
/**
* @var int
*/
private $umask;
/**
* @var int
*/
private $directoryStringLength;
/**
* @var int
*/
private $extensionStringLength;
/**
* @var bool
*/
private $isRunningOnWindows;
/**
* Constructor.
*
* @param string $directory The cache directory.
* @param string $extension The cache file extension.
*
* @throws \InvalidArgumentException
*/
public function __construct($directory, $extension = '', $umask = 0002)
{
// YES, this needs to be *before* createPathIfNeeded()
if ( ! is_int($umask)) {
throw new \InvalidArgumentException(sprintf(
'The umask parameter is required to be integer, was: %s',
gettype($umask)
));
}
$this->umask = $umask;
if ( ! $this->createPathIfNeeded($directory)) {
throw new \InvalidArgumentException(sprintf(
'The directory "%s" does not exist and could not be created.',
$directory
));
}
if ( ! is_writable($directory)) {
throw new \InvalidArgumentException(sprintf(
'The directory "%s" is not writable.',
$directory
));
}
// YES, this needs to be *after* createPathIfNeeded()
$this->directory = realpath($directory);
$this->extension = (string) $extension;
$this->directoryStringLength = strlen($this->directory);
$this->extensionStringLength = strlen($this->extension);
$this->isRunningOnWindows = defined('PHP_WINDOWS_VERSION_BUILD');
}
/**
* Gets the cache directory.
*
* @return string
*/
public function getDirectory()
{
return $this->directory;
}
/**
* Gets the cache file extension.
*
* @return string
*/
public function getExtension()
{
return $this->extension;
}
/**
* @param string $id
*
* @return string
*/
protected function getFilename($id)
{
$hash = hash('sha256', $id);
// This ensures that the filename is unique and that there are no invalid chars in it.
if (
'' === $id
|| ((strlen($id) * 2 + $this->extensionStringLength) > 255)
|| ($this->isRunningOnWindows && ($this->directoryStringLength + 4 + strlen($id) * 2 + $this->extensionStringLength) > 258)
) {
// Most filesystems have a limit of 255 chars for each path component. On Windows the the whole path is limited
// to 260 chars (including terminating null char). Using long UNC ("\\?\" prefix) does not work with the PHP API.
// And there is a bug in PHP (https://bugs.php.net/bug.php?id=70943) with path lengths of 259.
// So if the id in hex representation would surpass the limit, we use the hash instead. The prefix prevents
// collisions between the hash and bin2hex.
$filename = '_' . $hash;
} else {
$filename = bin2hex($id);
}
return $this->directory
. DIRECTORY_SEPARATOR
. substr($hash, 0, 2)
. DIRECTORY_SEPARATOR
. $filename
. $this->extension;
}
/**
* {@inheritdoc}
*/
protected function doDelete($id)
{
$filename = $this->getFilename($id);
return @unlink($filename) || ! file_exists($filename);
}
/**
* {@inheritdoc}
*/
protected function doFlush()
{
foreach ($this->getIterator() as $name => $file) {
if ($file->isDir()) {
// Remove the intermediate directories which have been created to balance the tree. It only takes effect
// if the directory is empty. If several caches share the same directory but with different file extensions,
// the other ones are not removed.
@rmdir($name);
} elseif ($this->isFilenameEndingWithExtension($name)) {
// If an extension is set, only remove files which end with the given extension.
// If no extension is set, we have no other choice than removing everything.
@unlink($name);
}
}
return true;
}
/**
* {@inheritdoc}
*/
protected function doGetStats()
{
$usage = 0;
foreach ($this->getIterator() as $name => $file) {
if (! $file->isDir() && $this->isFilenameEndingWithExtension($name)) {
$usage += $file->getSize();
}
}
$free = disk_free_space($this->directory);
return array(
Cache::STATS_HITS => null,
Cache::STATS_MISSES => null,
Cache::STATS_UPTIME => null,
Cache::STATS_MEMORY_USAGE => $usage,
Cache::STATS_MEMORY_AVAILABLE => $free,
);
}
/**
* Create path if needed.
*
* @param string $path
* @return bool TRUE on success or if path already exists, FALSE if path cannot be created.
*/
private function createPathIfNeeded($path)
{
if ( ! is_dir($path)) {
if (false === @mkdir($path, 0777 & (~$this->umask), true) && !is_dir($path)) {
return false;
}
}
return true;
}
/**
* Writes a string content to file in an atomic way.
*
* @param string $filename Path to the file where to write the data.
* @param string $content The content to write
*
* @return bool TRUE on success, FALSE if path cannot be created, if path is not writable or an any other error.
*/
protected function writeFile($filename, $content)
{
$filepath = pathinfo($filename, PATHINFO_DIRNAME);
if ( ! $this->createPathIfNeeded($filepath)) {
return false;
}
if ( ! is_writable($filepath)) {
return false;
}
$tmpFile = tempnam($filepath, 'swap');
@chmod($tmpFile, 0666 & (~$this->umask));
if (file_put_contents($tmpFile, $content) !== false) {
if (@rename($tmpFile, $filename)) {
return true;
}
@unlink($tmpFile);
}
return false;
}
/**
* @return \Iterator
*/
private function getIterator()
{
return new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($this->directory, \FilesystemIterator::SKIP_DOTS),
\RecursiveIteratorIterator::CHILD_FIRST
);
}
/**
* @param string $name The filename
*
* @return bool
*/
private function isFilenameEndingWithExtension($name)
{
return '' === $this->extension
|| strrpos($name, $this->extension) === (strlen($name) - $this->extensionStringLength);
}
}

View File

@ -0,0 +1,111 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
/**
* Filesystem cache driver.
*
* @since 2.3
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
*/
class FilesystemCache extends FileCache
{
const EXTENSION = '.doctrinecache.data';
/**
* {@inheritdoc}
*/
public function __construct($directory, $extension = self::EXTENSION, $umask = 0002)
{
parent::__construct($directory, $extension, $umask);
}
/**
* {@inheritdoc}
*/
protected function doFetch($id)
{
$data = '';
$lifetime = -1;
$filename = $this->getFilename($id);
if ( ! is_file($filename)) {
return false;
}
$resource = fopen($filename, "r");
if (false !== ($line = fgets($resource))) {
$lifetime = (int) $line;
}
if ($lifetime !== 0 && $lifetime < time()) {
fclose($resource);
return false;
}
while (false !== ($line = fgets($resource))) {
$data .= $line;
}
fclose($resource);
return unserialize($data);
}
/**
* {@inheritdoc}
*/
protected function doContains($id)
{
$lifetime = -1;
$filename = $this->getFilename($id);
if ( ! is_file($filename)) {
return false;
}
$resource = fopen($filename, "r");
if (false !== ($line = fgets($resource))) {
$lifetime = (int) $line;
}
fclose($resource);
return $lifetime === 0 || $lifetime > time();
}
/**
* {@inheritdoc}
*/
protected function doSave($id, $data, $lifeTime = 0)
{
if ($lifeTime > 0) {
$lifeTime = time() + $lifeTime;
}
$data = serialize($data);
$filename = $this->getFilename($id);
return $this->writeFile($filename, $lifeTime . PHP_EOL . $data);
}
}

View File

@ -0,0 +1,37 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
/**
* Interface for cache that can be flushed.
*
* @link www.doctrine-project.org
* @since 1.4
* @author Adirelle <adirelle@gmail.com>
*/
interface FlushableCache
{
/**
* Flushes all cache entries, globally.
*
* @return bool TRUE if the cache entries were successfully flushed, FALSE otherwise.
*/
public function flushAll();
}

View File

@ -0,0 +1,126 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
use \Memcache;
/**
* Memcache cache provider.
*
* @link www.doctrine-project.org
* @since 2.0
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
* @author David Abdemoulaie <dave@hobodave.com>
*/
class MemcacheCache extends CacheProvider
{
/**
* @var Memcache|null
*/
private $memcache;
/**
* Sets the memcache instance to use.
*
* @param Memcache $memcache
*
* @return void
*/
public function setMemcache(Memcache $memcache)
{
$this->memcache = $memcache;
}
/**
* Gets the memcache instance used by the cache.
*
* @return Memcache|null
*/
public function getMemcache()
{
return $this->memcache;
}
/**
* {@inheritdoc}
*/
protected function doFetch($id)
{
return $this->memcache->get($id);
}
/**
* {@inheritdoc}
*/
protected function doContains($id)
{
$flags = null;
$this->memcache->get($id, $flags);
//if memcache has changed the value of "flags", it means the value exists
return ($flags !== null);
}
/**
* {@inheritdoc}
*/
protected function doSave($id, $data, $lifeTime = 0)
{
if ($lifeTime > 30 * 24 * 3600) {
$lifeTime = time() + $lifeTime;
}
return $this->memcache->set($id, $data, 0, (int) $lifeTime);
}
/**
* {@inheritdoc}
*/
protected function doDelete($id)
{
// Memcache::delete() returns false if entry does not exist
return $this->memcache->delete($id) || ! $this->doContains($id);
}
/**
* {@inheritdoc}
*/
protected function doFlush()
{
return $this->memcache->flush();
}
/**
* {@inheritdoc}
*/
protected function doGetStats()
{
$stats = $this->memcache->getStats();
return array(
Cache::STATS_HITS => $stats['get_hits'],
Cache::STATS_MISSES => $stats['get_misses'],
Cache::STATS_UPTIME => $stats['uptime'],
Cache::STATS_MEMORY_USAGE => $stats['bytes'],
Cache::STATS_MEMORY_AVAILABLE => $stats['limit_maxbytes'],
);
}
}

View File

@ -0,0 +1,147 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
use \Memcached;
/**
* Memcached cache provider.
*
* @link www.doctrine-project.org
* @since 2.2
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
* @author David Abdemoulaie <dave@hobodave.com>
*/
class MemcachedCache extends CacheProvider
{
/**
* @var Memcached|null
*/
private $memcached;
/**
* Sets the memcache instance to use.
*
* @param Memcached $memcached
*
* @return void
*/
public function setMemcached(Memcached $memcached)
{
$this->memcached = $memcached;
}
/**
* Gets the memcached instance used by the cache.
*
* @return Memcached|null
*/
public function getMemcached()
{
return $this->memcached;
}
/**
* {@inheritdoc}
*/
protected function doFetch($id)
{
return $this->memcached->get($id);
}
/**
* {@inheritdoc}
*/
protected function doFetchMultiple(array $keys)
{
return $this->memcached->getMulti($keys) ?: [];
}
/**
* {@inheritdoc}
*/
protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
{
if ($lifetime > 30 * 24 * 3600) {
$lifetime = time() + $lifetime;
}
return $this->memcached->setMulti($keysAndValues, $lifetime);
}
/**
* {@inheritdoc}
*/
protected function doContains($id)
{
$this->memcached->get($id);
return $this->memcached->getResultCode() === Memcached::RES_SUCCESS;
}
/**
* {@inheritdoc}
*/
protected function doSave($id, $data, $lifeTime = 0)
{
if ($lifeTime > 30 * 24 * 3600) {
$lifeTime = time() + $lifeTime;
}
return $this->memcached->set($id, $data, (int) $lifeTime);
}
/**
* {@inheritdoc}
*/
protected function doDelete($id)
{
return $this->memcached->delete($id)
|| $this->memcached->getResultCode() === Memcached::RES_NOTFOUND;
}
/**
* {@inheritdoc}
*/
protected function doFlush()
{
return $this->memcached->flush();
}
/**
* {@inheritdoc}
*/
protected function doGetStats()
{
$stats = $this->memcached->getStats();
$servers = $this->memcached->getServerList();
$key = $servers[0]['host'] . ':' . $servers[0]['port'];
$stats = $stats[$key];
return array(
Cache::STATS_HITS => $stats['get_hits'],
Cache::STATS_MISSES => $stats['get_misses'],
Cache::STATS_UPTIME => $stats['uptime'],
Cache::STATS_MEMORY_USAGE => $stats['bytes'],
Cache::STATS_MEMORY_AVAILABLE => $stats['limit_maxbytes'],
);
}
}

View File

@ -0,0 +1,197 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
use MongoBinData;
use MongoCollection;
use MongoCursorException;
use MongoDate;
/**
* MongoDB cache provider.
*
* @since 1.1
* @author Jeremy Mikola <jmikola@gmail.com>
*/
class MongoDBCache extends CacheProvider
{
/**
* The data field will store the serialized PHP value.
*/
const DATA_FIELD = 'd';
/**
* The expiration field will store a MongoDate value indicating when the
* cache entry should expire.
*
* With MongoDB 2.2+, entries can be automatically deleted by MongoDB by
* indexing this field with the "expireAfterSeconds" option equal to zero.
* This will direct MongoDB to regularly query for and delete any entries
* whose date is older than the current time. Entries without a date value
* in this field will be ignored.
*
* The cache provider will also check dates on its own, in case expired
* entries are fetched before MongoDB's TTLMonitor pass can expire them.
*
* @see http://docs.mongodb.org/manual/tutorial/expire-data/
*/
const EXPIRATION_FIELD = 'e';
/**
* @var MongoCollection
*/
private $collection;
/**
* Constructor.
*
* This provider will default to the write concern and read preference
* options set on the MongoCollection instance (or inherited from MongoDB or
* MongoClient). Using an unacknowledged write concern (< 1) may make the
* return values of delete() and save() unreliable. Reading from secondaries
* may make contain() and fetch() unreliable.
*
* @see http://www.php.net/manual/en/mongo.readpreferences.php
* @see http://www.php.net/manual/en/mongo.writeconcerns.php
* @param MongoCollection $collection
*/
public function __construct(MongoCollection $collection)
{
$this->collection = $collection;
}
/**
* {@inheritdoc}
*/
protected function doFetch($id)
{
$document = $this->collection->findOne(array('_id' => $id), array(self::DATA_FIELD, self::EXPIRATION_FIELD));
if ($document === null) {
return false;
}
if ($this->isExpired($document)) {
$this->doDelete($id);
return false;
}
return unserialize($document[self::DATA_FIELD]->bin);
}
/**
* {@inheritdoc}
*/
protected function doContains($id)
{
$document = $this->collection->findOne(array('_id' => $id), array(self::EXPIRATION_FIELD));
if ($document === null) {
return false;
}
if ($this->isExpired($document)) {
$this->doDelete($id);
return false;
}
return true;
}
/**
* {@inheritdoc}
*/
protected function doSave($id, $data, $lifeTime = 0)
{
try {
$result = $this->collection->update(
array('_id' => $id),
array('$set' => array(
self::EXPIRATION_FIELD => ($lifeTime > 0 ? new MongoDate(time() + $lifeTime) : null),
self::DATA_FIELD => new MongoBinData(serialize($data), MongoBinData::BYTE_ARRAY),
)),
array('upsert' => true, 'multiple' => false)
);
} catch (MongoCursorException $e) {
return false;
}
return isset($result['ok']) ? $result['ok'] == 1 : true;
}
/**
* {@inheritdoc}
*/
protected function doDelete($id)
{
$result = $this->collection->remove(array('_id' => $id));
return isset($result['ok']) ? $result['ok'] == 1 : true;
}
/**
* {@inheritdoc}
*/
protected function doFlush()
{
// Use remove() in lieu of drop() to maintain any collection indexes
$result = $this->collection->remove();
return isset($result['ok']) ? $result['ok'] == 1 : true;
}
/**
* {@inheritdoc}
*/
protected function doGetStats()
{
$serverStatus = $this->collection->db->command(array(
'serverStatus' => 1,
'locks' => 0,
'metrics' => 0,
'recordStats' => 0,
'repl' => 0,
));
$collStats = $this->collection->db->command(array('collStats' => 1));
return array(
Cache::STATS_HITS => null,
Cache::STATS_MISSES => null,
Cache::STATS_UPTIME => (isset($serverStatus['uptime']) ? (int) $serverStatus['uptime'] : null),
Cache::STATS_MEMORY_USAGE => (isset($collStats['size']) ? (int) $collStats['size'] : null),
Cache::STATS_MEMORY_AVAILABLE => null,
);
}
/**
* Check if the document is expired.
*
* @param array $document
*
* @return bool
*/
private function isExpired(array $document)
{
return isset($document[self::EXPIRATION_FIELD]) &&
$document[self::EXPIRATION_FIELD] instanceof MongoDate &&
$document[self::EXPIRATION_FIELD]->sec < time();
}
}

View File

@ -0,0 +1,39 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
/**
* Interface for cache drivers that allows to get many items at once.
*
* @link www.doctrine-project.org
* @since 1.4
* @author Asmir Mustafic <goetas@gmail.com>
*/
interface MultiGetCache
{
/**
* Returns an associative array of values for keys is found in cache.
*
* @param string[] $keys Array of keys to retrieve from cache
* @return mixed[] Array of retrieved values, indexed by the specified keys.
* Values that couldn't be retrieved are not contained in this array.
*/
function fetchMultiple(array $keys);
}

View File

@ -0,0 +1,41 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
/**
* Interface for cache drivers that allows to put many items at once.
*
* @link www.doctrine-project.org
* @since 1.6
* @author Daniel Gorgan <danut007ro@gmail.com>
*/
interface MultiPutCache
{
/**
* Returns a boolean value indicating if the operation succeeded.
*
* @param array $keysAndValues Array of keys and values to save in cache
* @param int $lifetime The lifetime. If != 0, sets a specific lifetime for these
* cache entries (0 => infinite lifeTime).
*
* @return bool TRUE if the operation was successful, FALSE if it wasn't.
*/
function saveMultiple(array $keysAndValues, $lifetime = 0);
}

View File

@ -0,0 +1,120 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
/**
* Php file cache driver.
*
* @since 2.3
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
*/
class PhpFileCache extends FileCache
{
const EXTENSION = '.doctrinecache.php';
/**
* {@inheritdoc}
*/
public function __construct($directory, $extension = self::EXTENSION, $umask = 0002)
{
parent::__construct($directory, $extension, $umask);
}
/**
* {@inheritdoc}
*/
protected function doFetch($id)
{
$value = $this->includeFileForId($id);
if (! $value) {
return false;
}
if ($value['lifetime'] !== 0 && $value['lifetime'] < time()) {
return false;
}
return $value['data'];
}
/**
* {@inheritdoc}
*/
protected function doContains($id)
{
$value = $this->includeFileForId($id);
if (! $value) {
return false;
}
return $value['lifetime'] === 0 || $value['lifetime'] > time();
}
/**
* {@inheritdoc}
*/
protected function doSave($id, $data, $lifeTime = 0)
{
if ($lifeTime > 0) {
$lifeTime = time() + $lifeTime;
}
if (is_object($data) && ! method_exists($data, '__set_state')) {
throw new \InvalidArgumentException(
"Invalid argument given, PhpFileCache only allows objects that implement __set_state() " .
"and fully support var_export(). You can use the FilesystemCache to save arbitrary object " .
"graphs using serialize()/deserialize()."
);
}
$filename = $this->getFilename($id);
$value = array(
'lifetime' => $lifeTime,
'data' => $data
);
$value = var_export($value, true);
$code = sprintf('<?php return %s;', $value);
return $this->writeFile($filename, $code);
}
/**
* @param string $id
*
* @return array|false
*/
private function includeFileForId($id)
{
$fileName = $this->getFilename($id);
// note: error suppression is still faster than `file_exists`, `is_file` and `is_readable`
$value = @include $fileName;
if (! isset($value['lifetime'])) {
return false;
}
return $value;
}
}

View File

@ -0,0 +1,136 @@
<?php
namespace Doctrine\Common\Cache;
use Predis\ClientInterface;
/**
* Predis cache provider.
*
* @author othillo <othillo@othillo.nl>
*/
class PredisCache extends CacheProvider
{
/**
* @var ClientInterface
*/
private $client;
/**
* @param ClientInterface $client
*
* @return void
*/
public function __construct(ClientInterface $client)
{
$this->client = $client;
}
/**
* {@inheritdoc}
*/
protected function doFetch($id)
{
$result = $this->client->get($id);
if (null === $result) {
return false;
}
return unserialize($result);
}
/**
* {@inheritdoc}
*/
protected function doFetchMultiple(array $keys)
{
$fetchedItems = call_user_func_array(array($this->client, 'mget'), $keys);
return array_map('unserialize', array_filter(array_combine($keys, $fetchedItems)));
}
/**
* {@inheritdoc}
*/
protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
{
if ($lifetime) {
$success = true;
// Keys have lifetime, use SETEX for each of them
foreach ($keysAndValues as $key => $value) {
$response = $this->client->setex($key, $lifetime, serialize($value));
if ((string) $response != 'OK') {
$success = false;
}
}
return $success;
}
// No lifetime, use MSET
$response = $this->client->mset(array_map(function ($value) {
return serialize($value);
}, $keysAndValues));
return (string) $response == 'OK';
}
/**
* {@inheritdoc}
*/
protected function doContains($id)
{
return (bool) $this->client->exists($id);
}
/**
* {@inheritdoc}
*/
protected function doSave($id, $data, $lifeTime = 0)
{
$data = serialize($data);
if ($lifeTime > 0) {
$response = $this->client->setex($id, $lifeTime, $data);
} else {
$response = $this->client->set($id, $data);
}
return $response === true || $response == 'OK';
}
/**
* {@inheritdoc}
*/
protected function doDelete($id)
{
return $this->client->del($id) >= 0;
}
/**
* {@inheritdoc}
*/
protected function doFlush()
{
$response = $this->client->flushdb();
return $response === true || $response == 'OK';
}
/**
* {@inheritdoc}
*/
protected function doGetStats()
{
$info = $this->client->info();
return array(
Cache::STATS_HITS => $info['Stats']['keyspace_hits'],
Cache::STATS_MISSES => $info['Stats']['keyspace_misses'],
Cache::STATS_UPTIME => $info['Server']['uptime_in_seconds'],
Cache::STATS_MEMORY_USAGE => $info['Memory']['used_memory'],
Cache::STATS_MEMORY_AVAILABLE => false
);
}
}

View File

@ -0,0 +1,180 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
use Redis;
/**
* Redis cache provider.
*
* @link www.doctrine-project.org
* @since 2.2
* @author Osman Ungur <osmanungur@gmail.com>
*/
class RedisCache extends CacheProvider
{
/**
* @var Redis|null
*/
private $redis;
/**
* Sets the redis instance to use.
*
* @param Redis $redis
*
* @return void
*/
public function setRedis(Redis $redis)
{
$redis->setOption(Redis::OPT_SERIALIZER, $this->getSerializerValue());
$this->redis = $redis;
}
/**
* Gets the redis instance used by the cache.
*
* @return Redis|null
*/
public function getRedis()
{
return $this->redis;
}
/**
* {@inheritdoc}
*/
protected function doFetch($id)
{
return $this->redis->get($id);
}
/**
* {@inheritdoc}
*/
protected function doFetchMultiple(array $keys)
{
$fetchedItems = array_combine($keys, $this->redis->mget($keys));
// Redis mget returns false for keys that do not exist. So we need to filter those out unless it's the real data.
$foundItems = array();
foreach ($fetchedItems as $key => $value) {
if (false !== $value || $this->redis->exists($key)) {
$foundItems[$key] = $value;
}
}
return $foundItems;
}
/**
* {@inheritdoc}
*/
protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
{
if ($lifetime) {
$success = true;
// Keys have lifetime, use SETEX for each of them
foreach ($keysAndValues as $key => $value) {
if (!$this->redis->setex($key, $lifetime, $value)) {
$success = false;
}
}
return $success;
}
// No lifetime, use MSET
return (bool) $this->redis->mset($keysAndValues);
}
/**
* {@inheritdoc}
*/
protected function doContains($id)
{
return $this->redis->exists($id);
}
/**
* {@inheritdoc}
*/
protected function doSave($id, $data, $lifeTime = 0)
{
if ($lifeTime > 0) {
return $this->redis->setex($id, $lifeTime, $data);
}
return $this->redis->set($id, $data);
}
/**
* {@inheritdoc}
*/
protected function doDelete($id)
{
return $this->redis->delete($id) >= 0;
}
/**
* {@inheritdoc}
*/
protected function doFlush()
{
return $this->redis->flushDB();
}
/**
* {@inheritdoc}
*/
protected function doGetStats()
{
$info = $this->redis->info();
return array(
Cache::STATS_HITS => $info['keyspace_hits'],
Cache::STATS_MISSES => $info['keyspace_misses'],
Cache::STATS_UPTIME => $info['uptime_in_seconds'],
Cache::STATS_MEMORY_USAGE => $info['used_memory'],
Cache::STATS_MEMORY_AVAILABLE => false
);
}
/**
* Returns the serializer constant to use. If Redis is compiled with
* igbinary support, that is used. Otherwise the default PHP serializer is
* used.
*
* @return integer One of the Redis::SERIALIZER_* constants
*/
protected function getSerializerValue()
{
if (defined('HHVM_VERSION')) {
return Redis::SERIALIZER_PHP;
}
if (defined('Redis::SERIALIZER_IGBINARY') && extension_loaded('igbinary')) {
return Redis::SERIALIZER_IGBINARY;
}
return Redis::SERIALIZER_PHP;
}
}

View File

@ -0,0 +1,250 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
use Riak\Bucket;
use Riak\Connection;
use Riak\Input;
use Riak\Exception;
use Riak\Object;
/**
* Riak cache provider.
*
* @link www.doctrine-project.org
* @since 1.1
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
*/
class RiakCache extends CacheProvider
{
const EXPIRES_HEADER = 'X-Riak-Meta-Expires';
/**
* @var \Riak\Bucket
*/
private $bucket;
/**
* Sets the riak bucket instance to use.
*
* @param \Riak\Bucket $bucket
*/
public function __construct(Bucket $bucket)
{
$this->bucket = $bucket;
}
/**
* {@inheritdoc}
*/
protected function doFetch($id)
{
try {
$response = $this->bucket->get($id);
// No objects found
if ( ! $response->hasObject()) {
return false;
}
// Check for attempted siblings
$object = ($response->hasSiblings())
? $this->resolveConflict($id, $response->getVClock(), $response->getObjectList())
: $response->getFirstObject();
// Check for expired object
if ($this->isExpired($object)) {
$this->bucket->delete($object);
return false;
}
return unserialize($object->getContent());
} catch (Exception\RiakException $e) {
// Covers:
// - Riak\ConnectionException
// - Riak\CommunicationException
// - Riak\UnexpectedResponseException
// - Riak\NotFoundException
}
return false;
}
/**
* {@inheritdoc}
*/
protected function doContains($id)
{
try {
// We only need the HEAD, not the entire object
$input = new Input\GetInput();
$input->setReturnHead(true);
$response = $this->bucket->get($id, $input);
// No objects found
if ( ! $response->hasObject()) {
return false;
}
$object = $response->getFirstObject();
// Check for expired object
if ($this->isExpired($object)) {
$this->bucket->delete($object);
return false;
}
return true;
} catch (Exception\RiakException $e) {
// Do nothing
}
return false;
}
/**
* {@inheritdoc}
*/
protected function doSave($id, $data, $lifeTime = 0)
{
try {
$object = new Object($id);
$object->setContent(serialize($data));
if ($lifeTime > 0) {
$object->addMetadata(self::EXPIRES_HEADER, (string) (time() + $lifeTime));
}
$this->bucket->put($object);
return true;
} catch (Exception\RiakException $e) {
// Do nothing
}
return false;
}
/**
* {@inheritdoc}
*/
protected function doDelete($id)
{
try {
$this->bucket->delete($id);
return true;
} catch (Exception\BadArgumentsException $e) {
// Key did not exist on cluster already
} catch (Exception\RiakException $e) {
// Covers:
// - Riak\Exception\ConnectionException
// - Riak\Exception\CommunicationException
// - Riak\Exception\UnexpectedResponseException
}
return false;
}
/**
* {@inheritdoc}
*/
protected function doFlush()
{
try {
$keyList = $this->bucket->getKeyList();
foreach ($keyList as $key) {
$this->bucket->delete($key);
}
return true;
} catch (Exception\RiakException $e) {
// Do nothing
}
return false;
}
/**
* {@inheritdoc}
*/
protected function doGetStats()
{
// Only exposed through HTTP stats API, not Protocol Buffers API
return null;
}
/**
* Check if a given Riak Object have expired.
*
* @param \Riak\Object $object
*
* @return bool
*/
private function isExpired(Object $object)
{
$metadataMap = $object->getMetadataMap();
return isset($metadataMap[self::EXPIRES_HEADER])
&& $metadataMap[self::EXPIRES_HEADER] < time();
}
/**
* On-read conflict resolution. Applied approach here is last write wins.
* Specific needs may override this method to apply alternate conflict resolutions.
*
* {@internal Riak does not attempt to resolve a write conflict, and store
* it as sibling of conflicted one. By following this approach, it is up to
* the next read to resolve the conflict. When this happens, your fetched
* object will have a list of siblings (read as a list of objects).
* In our specific case, we do not care about the intermediate ones since
* they are all the same read from storage, and we do apply a last sibling
* (last write) wins logic.
* If by any means our resolution generates another conflict, it'll up to
* next read to properly solve it.}
*
* @param string $id
* @param string $vClock
* @param array $objectList
*
* @return \Riak\Object
*/
protected function resolveConflict($id, $vClock, array $objectList)
{
// Our approach here is last-write wins
$winner = $objectList[count($objectList)];
$putInput = new Input\PutInput();
$putInput->setVClock($vClock);
$mergedObject = new Object($id);
$mergedObject->setContent($winner->getContent());
$this->bucket->put($mergedObject, $putInput);
return $mergedObject;
}
}

View File

@ -0,0 +1,220 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
use SQLite3;
use SQLite3Result;
/**
* SQLite3 cache provider.
*
* @since 1.4
* @author Jake Bell <jake@theunraveler.com>
*/
class SQLite3Cache extends CacheProvider
{
/**
* The ID field will store the cache key.
*/
const ID_FIELD = 'k';
/**
* The data field will store the serialized PHP value.
*/
const DATA_FIELD = 'd';
/**
* The expiration field will store a date value indicating when the
* cache entry should expire.
*/
const EXPIRATION_FIELD = 'e';
/**
* @var SQLite3
*/
private $sqlite;
/**
* @var string
*/
private $table;
/**
* Constructor.
*
* Calling the constructor will ensure that the database file and table
* exist and will create both if they don't.
*
* @param SQLite3 $sqlite
* @param string $table
*/
public function __construct(SQLite3 $sqlite, $table)
{
$this->sqlite = $sqlite;
$this->table = (string) $table;
list($id, $data, $exp) = $this->getFields();
return $this->sqlite->exec(sprintf(
'CREATE TABLE IF NOT EXISTS %s(%s TEXT PRIMARY KEY NOT NULL, %s BLOB, %s INTEGER)',
$table,
$id,
$data,
$exp
));
}
/**
* {@inheritdoc}
*/
protected function doFetch($id)
{
if ($item = $this->findById($id)) {
return unserialize($item[self::DATA_FIELD]);
}
return false;
}
/**
* {@inheritdoc}
*/
protected function doContains($id)
{
return null !== $this->findById($id, false);
}
/**
* {@inheritdoc}
*/
protected function doSave($id, $data, $lifeTime = 0)
{
$statement = $this->sqlite->prepare(sprintf(
'INSERT OR REPLACE INTO %s (%s) VALUES (:id, :data, :expire)',
$this->table,
implode(',', $this->getFields())
));
$statement->bindValue(':id', $id);
$statement->bindValue(':data', serialize($data), SQLITE3_BLOB);
$statement->bindValue(':expire', $lifeTime > 0 ? time() + $lifeTime : null);
return $statement->execute() instanceof SQLite3Result;
}
/**
* {@inheritdoc}
*/
protected function doDelete($id)
{
list($idField) = $this->getFields();
$statement = $this->sqlite->prepare(sprintf(
'DELETE FROM %s WHERE %s = :id',
$this->table,
$idField
));
$statement->bindValue(':id', $id);
return $statement->execute() instanceof SQLite3Result;
}
/**
* {@inheritdoc}
*/
protected function doFlush()
{
return $this->sqlite->exec(sprintf('DELETE FROM %s', $this->table));
}
/**
* {@inheritdoc}
*/
protected function doGetStats()
{
// no-op.
}
/**
* Find a single row by ID.
*
* @param mixed $id
* @param bool $includeData
*
* @return array|null
*/
private function findById($id, $includeData = true)
{
list($idField) = $fields = $this->getFields();
if (!$includeData) {
$key = array_search(static::DATA_FIELD, $fields);
unset($fields[$key]);
}
$statement = $this->sqlite->prepare(sprintf(
'SELECT %s FROM %s WHERE %s = :id LIMIT 1',
implode(',', $fields),
$this->table,
$idField
));
$statement->bindValue(':id', $id, SQLITE3_TEXT);
$item = $statement->execute()->fetchArray(SQLITE3_ASSOC);
if ($item === false) {
return null;
}
if ($this->isExpired($item)) {
$this->doDelete($id);
return null;
}
return $item;
}
/**
* Gets an array of the fields in our table.
*
* @return array
*/
private function getFields()
{
return array(static::ID_FIELD, static::DATA_FIELD, static::EXPIRATION_FIELD);
}
/**
* Check if the item is expired.
*
* @param array $item
*
* @return bool
*/
private function isExpired(array $item)
{
return isset($item[static::EXPIRATION_FIELD]) &&
$item[self::EXPIRATION_FIELD] !== null &&
$item[self::EXPIRATION_FIELD] < time();
}
}

View File

@ -0,0 +1,25 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
class Version
{
const VERSION = '1.6.1-DEV';
}

View File

@ -0,0 +1,78 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
/**
* Void cache driver. The cache could be of use in tests where you don`t need to cache anything.
*
* @link www.doctrine-project.org
* @since 1.5
* @author Kotlyar Maksim <kotlyar.maksim@gmail.com>
*/
class VoidCache extends CacheProvider
{
/**
* {@inheritDoc}
*/
protected function doFetch($id)
{
return false;
}
/**
* {@inheritDoc}
*/
protected function doContains($id)
{
return false;
}
/**
* {@inheritDoc}
*/
protected function doSave($id, $data, $lifeTime = 0)
{
return true;
}
/**
* {@inheritDoc}
*/
protected function doDelete($id)
{
return true;
}
/**
* {@inheritDoc}
*/
protected function doFlush()
{
return true;
}
/**
* {@inheritDoc}
*/
protected function doGetStats()
{
return;
}
}

View File

@ -0,0 +1,109 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
/**
* WinCache cache provider.
*
* @link www.doctrine-project.org
* @since 2.2
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
* @author David Abdemoulaie <dave@hobodave.com>
*/
class WinCacheCache extends CacheProvider
{
/**
* {@inheritdoc}
*/
protected function doFetch($id)
{
return wincache_ucache_get($id);
}
/**
* {@inheritdoc}
*/
protected function doContains($id)
{
return wincache_ucache_exists($id);
}
/**
* {@inheritdoc}
*/
protected function doSave($id, $data, $lifeTime = 0)
{
return wincache_ucache_set($id, $data, $lifeTime);
}
/**
* {@inheritdoc}
*/
protected function doDelete($id)
{
return wincache_ucache_delete($id);
}
/**
* {@inheritdoc}
*/
protected function doFlush()
{
return wincache_ucache_clear();
}
/**
* {@inheritdoc}
*/
protected function doFetchMultiple(array $keys)
{
return wincache_ucache_get($keys);
}
/**
* {@inheritdoc}
*/
protected function doSaveMultiple(array $keysAndValues, $lifetime = 0)
{
$result = wincache_ucache_set($keysAndValues, null, $lifetime);
return empty($result);
}
/**
* {@inheritdoc}
*/
protected function doGetStats()
{
$info = wincache_ucache_info();
$meminfo = wincache_ucache_meminfo();
return array(
Cache::STATS_HITS => $info['total_hit_count'],
Cache::STATS_MISSES => $info['total_miss_count'],
Cache::STATS_UPTIME => $info['total_cache_uptime'],
Cache::STATS_MEMORY_USAGE => $meminfo['memory_total'],
Cache::STATS_MEMORY_AVAILABLE => $meminfo['memory_free'],
);
}
}

View File

@ -0,0 +1,112 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
/**
* Xcache cache driver.
*
* @link www.doctrine-project.org
* @since 2.0
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
* @author David Abdemoulaie <dave@hobodave.com>
*/
class XcacheCache extends CacheProvider
{
/**
* {@inheritdoc}
*/
protected function doFetch($id)
{
return $this->doContains($id) ? unserialize(xcache_get($id)) : false;
}
/**
* {@inheritdoc}
*/
protected function doContains($id)
{
return xcache_isset($id);
}
/**
* {@inheritdoc}
*/
protected function doSave($id, $data, $lifeTime = 0)
{
return xcache_set($id, serialize($data), (int) $lifeTime);
}
/**
* {@inheritdoc}
*/
protected function doDelete($id)
{
return xcache_unset($id);
}
/**
* {@inheritdoc}
*/
protected function doFlush()
{
$this->checkAuthorization();
xcache_clear_cache(XC_TYPE_VAR);
return true;
}
/**
* Checks that xcache.admin.enable_auth is Off.
*
* @return void
*
* @throws \BadMethodCallException When xcache.admin.enable_auth is On.
*/
protected function checkAuthorization()
{
if (ini_get('xcache.admin.enable_auth')) {
throw new \BadMethodCallException(
'To use all features of \Doctrine\Common\Cache\XcacheCache, '
. 'you must set "xcache.admin.enable_auth" to "Off" in your php.ini.'
);
}
}
/**
* {@inheritdoc}
*/
protected function doGetStats()
{
$this->checkAuthorization();
$info = xcache_info(XC_TYPE_VAR, 0);
return array(
Cache::STATS_HITS => $info['hits'],
Cache::STATS_MISSES => $info['misses'],
Cache::STATS_UPTIME => null,
Cache::STATS_MEMORY_USAGE => $info['size'],
Cache::STATS_MEMORY_AVAILABLE => $info['avail'],
);
}
}

View File

@ -0,0 +1,83 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\Common\Cache;
/**
* Zend Data Cache cache driver.
*
* @link www.doctrine-project.org
* @since 2.0
* @author Ralph Schindler <ralph.schindler@zend.com>
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
*/
class ZendDataCache extends CacheProvider
{
/**
* {@inheritdoc}
*/
protected function doFetch($id)
{
return zend_shm_cache_fetch($id);
}
/**
* {@inheritdoc}
*/
protected function doContains($id)
{
return (false !== zend_shm_cache_fetch($id));
}
/**
* {@inheritdoc}
*/
protected function doSave($id, $data, $lifeTime = 0)
{
return zend_shm_cache_store($id, $data, $lifeTime);
}
/**
* {@inheritdoc}
*/
protected function doDelete($id)
{
return zend_shm_cache_delete($id);
}
/**
* {@inheritdoc}
*/
protected function doFlush()
{
$namespace = $this->getNamespace();
if (empty($namespace)) {
return zend_shm_cache_clear();
}
return zend_shm_cache_clear($namespace);
}
/**
* {@inheritdoc}
*/
protected function doGetStats()
{
return null;
}
}

2
version Normal file
View File

@ -0,0 +1,2 @@
20200118.01
SCF、heroku、普通VPS三种环境都可以用了。

3
writeable.sh Normal file
View File

@ -0,0 +1,3 @@
OneManagerPath=`cd $(dirname $0);pwd -P`
cd ${OneManagerPath}
chmod 666 config.php