├── Applications ├── Email │ ├── EmailWorker.php │ └── start.php ├── Sms │ ├── SmsWorker.php │ └── start.php ├── Todpole │ ├── Config │ │ └── Store.php │ ├── Event.php │ ├── Web │ │ ├── auth.html │ │ ├── css │ │ │ ├── images │ │ │ │ ├── github.png │ │ │ │ └── logo.png │ │ │ └── main.css │ │ ├── favicon.ico │ │ ├── images │ │ │ ├── apple-touch-icon.png │ │ │ ├── fb-image.jpg │ │ │ └── workerman-todpole-browser.png │ │ ├── index.php │ │ └── js │ │ │ ├── App.js │ │ │ ├── Arrow.js │ │ │ ├── Camera.js │ │ │ ├── Cookie.js │ │ │ ├── Keys.js │ │ │ ├── Message.js │ │ │ ├── Model.js │ │ │ ├── Settings.js │ │ │ ├── Tadpole.js │ │ │ ├── TadpoleTail.js │ │ │ ├── WaterParticle.js │ │ │ ├── WebSocketService.js │ │ │ ├── formControls.js │ │ │ ├── frogMode.js │ │ │ ├── jquery.min.js │ │ │ ├── lib │ │ │ ├── Stats.js │ │ │ ├── jquery-1.4.2.min.js │ │ │ ├── modernizr-1.5.min.js │ │ │ └── parseUri.js │ │ │ └── main.js │ └── start-bak.php └── config.php ├── GatewayWorker ├── BusinessWorker.php ├── Gateway.php └── Lib │ ├── Context.php │ ├── Db.php │ ├── DbConnection.php │ ├── Gateway.php │ ├── Lock.php │ ├── Store.php │ └── StoreDriver │ └── File.php ├── PHPMailer ├── .scrutinizer.yml ├── .travis.yml ├── LICENSE ├── PHPMailerAutoload.php ├── README.md ├── VERSION ├── changelog.md ├── class.phpmailer.php ├── class.pop3.php ├── class.smtp.php ├── composer.json ├── docs │ ├── Callback_function_notes.txt │ ├── DomainKeys_notes.txt │ ├── Note_for_SMTP_debugging.txt │ ├── extending.html │ ├── faq.html │ ├── generatedocs.sh │ └── pop3_article.txt ├── examples │ ├── LGPLv3.txt │ ├── code_generator.phps │ ├── contents.html │ ├── exceptions.phps │ ├── gmail.phps │ ├── images │ │ ├── phpmailer.png │ │ └── phpmailer_mini.png │ ├── index.html │ ├── mail.phps │ ├── mailing_list.phps │ ├── pop_before_smtp.phps │ ├── scripts │ │ ├── XRegExp.js │ │ ├── shAutoloader.js │ │ ├── shBrushPhp.js │ │ ├── shCore.js │ │ └── shLegacy.js │ ├── sendmail.phps │ ├── smtp.phps │ ├── smtp_check.phps │ ├── smtp_no_auth.phps │ └── styles │ │ ├── shCore.css │ │ ├── shCoreDefault.css │ │ ├── shCoreDjango.css │ │ ├── shCoreEclipse.css │ │ ├── shCoreEmacs.css │ │ ├── shCoreFadeToGrey.css │ │ ├── shCoreMDUltra.css │ │ ├── shCoreMidnight.css │ │ ├── shCoreRDark.css │ │ ├── shThemeAppleScript.css │ │ ├── shThemeDefault.css │ │ ├── shThemeDjango.css │ │ ├── shThemeEclipse.css │ │ ├── shThemeEmacs.css │ │ ├── shThemeFadeToGrey.css │ │ ├── shThemeMDUltra.css │ │ ├── shThemeMidnight.css │ │ ├── shThemeRDark.css │ │ ├── shThemeVisualStudio.css │ │ └── wrapping.png ├── extras │ ├── EasyPeasyICS.php │ ├── README.md │ ├── class.html2text.php │ ├── htmlfilter.php │ └── ntlm_sasl_client.php ├── language │ ├── phpmailer.lang-ar.php │ ├── phpmailer.lang-az.php │ ├── phpmailer.lang-be.php │ ├── phpmailer.lang-br.php │ ├── phpmailer.lang-ca.php │ ├── phpmailer.lang-ch.php │ ├── phpmailer.lang-cz.php │ ├── phpmailer.lang-de.php │ ├── phpmailer.lang-dk.php │ ├── phpmailer.lang-el.php │ ├── phpmailer.lang-eo.php │ ├── phpmailer.lang-es.php │ ├── phpmailer.lang-et.php │ ├── phpmailer.lang-fa.php │ ├── phpmailer.lang-fi.php │ ├── phpmailer.lang-fo.php │ ├── phpmailer.lang-fr.php │ ├── phpmailer.lang-gl.php │ ├── phpmailer.lang-he.php │ ├── phpmailer.lang-hr.php │ ├── phpmailer.lang-hu.php │ ├── phpmailer.lang-id.php │ ├── phpmailer.lang-it.php │ ├── phpmailer.lang-ja.php │ ├── phpmailer.lang-ka.php │ ├── phpmailer.lang-lt.php │ ├── phpmailer.lang-lv.php │ ├── phpmailer.lang-nl.php │ ├── phpmailer.lang-no.php │ ├── phpmailer.lang-pl.php │ ├── phpmailer.lang-pt.php │ ├── phpmailer.lang-ro.php │ ├── phpmailer.lang-ru.php │ ├── phpmailer.lang-se.php │ ├── phpmailer.lang-sk.php │ ├── phpmailer.lang-sr.php │ ├── phpmailer.lang-tr.php │ ├── phpmailer.lang-uk.php │ ├── phpmailer.lang-vi.php │ ├── phpmailer.lang-zh.php │ └── phpmailer.lang-zh_cn.php ├── test │ ├── bootstrap.php │ ├── fakepopserver.sh │ ├── fakesendmail.sh │ ├── phpmailerLangTest.php │ ├── phpmailerTest.php │ ├── runfakepopserver.sh │ ├── test_callback.php │ └── testbootstrap-dist.php └── travis.phpunit.xml.dist ├── README.md ├── Workerman ├── Autoloader.php ├── Connection │ ├── AsyncTcpConnection.php │ ├── ConnectionInterface.php │ ├── TcpConnection.php │ └── UdpConnection.php ├── Events │ ├── EventInterface.php │ ├── Libevent.php │ └── Select.php ├── Lib │ ├── Constants.php │ └── Timer.php ├── Protocols │ ├── GatewayProtocol.php │ ├── Http.php │ ├── Http │ │ └── mime.types │ ├── ProtocolInterface.php │ ├── Text.php │ └── Websocket.php ├── WebServer.php └── Worker.php └── start.php /Applications/Email/start.php: -------------------------------------------------------------------------------- 1 | name = 'EmailWorker'; 15 | // Worker进程数量 16 | $worker->count = 10; 17 | 18 | $worker->onWorkerStart = function($worker) { 19 | //echo 'process '.getmypid(). ' start'."\n"; 20 | $Email = new EmailWorker(); 21 | $Email->start(); 22 | }; 23 | 24 | // 如果不是在根目录启动,则运行runAll方法 25 | if(!defined('GLOBAL_START')) 26 | { 27 | Worker::runAll(); 28 | } 29 | -------------------------------------------------------------------------------- /Applications/Sms/start.php: -------------------------------------------------------------------------------- 1 | name = 'SmsWorker'; 15 | // Worker进程数量 16 | $worker->count = 10; 17 | 18 | $worker->onWorkerStart = function($worker) { 19 | //echo 'process '.getmypid(). ' start'."\n"; 20 | $Sms = new SmsWorker(); 21 | $Sms->start(); 22 | }; 23 | 24 | // 如果不是在根目录启动,则运行runAll方法 25 | if(!defined('GLOBAL_START')) 26 | { 27 | Worker::runAll(); 28 | } 29 | -------------------------------------------------------------------------------- /Applications/Todpole/Config/Store.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | */ 9 | 10 | use \GatewayWorker\Lib\Gateway; 11 | 12 | class Event 13 | { 14 | /** 15 | * 有消息时 16 | * @param int $client_id 17 | * @param string $message 18 | */ 19 | public static function onMessage($client_id, $message) 20 | { 21 | // 获取客户端请求 22 | $message_data = json_decode($message, true); 23 | if(!$message_data) 24 | { 25 | return ; 26 | } 27 | 28 | switch($message_data['type']) 29 | { 30 | case 'login': 31 | Gateway::sendToCurrentClient('{"type":"welcome","id":'.$client_id.'}'); 32 | break; 33 | // 更新用户 34 | case 'update': 35 | // 转播给所有用户 36 | Gateway::sendToAll(json_encode( 37 | array( 38 | 'type' => 'update', 39 | 'id' => $client_id, 40 | 'angle' => $message_data["angle"]+0, 41 | 'momentum' => $message_data["momentum"]+0, 42 | 'x' => $message_data["x"]+0, 43 | 'y' => $message_data["y"]+0, 44 | 'life' => 1, 45 | 'name' => isset($message_data['name']) ? $message_data['name'] : 'Guest.'.$client_id, 46 | 'authorized' => false, 47 | ) 48 | )); 49 | return; 50 | // 聊天 51 | case 'message': 52 | // 向大家说 53 | $new_message = array( 54 | 'type'=>'message', 55 | 'id'=>$client_id, 56 | 'message'=>$message_data['message'], 57 | ); 58 | return Gateway::sendToAll(json_encode($new_message)); 59 | } 60 | } 61 | 62 | /** 63 | * 当用户断开连接时 64 | * @param integer $client_id 用户id 65 | */ 66 | public static function onClose($client_id) 67 | { 68 | // 广播 xxx 退出了 69 | GateWay::sendToAll(json_encode(array('type'=>'closed', 'id'=>$client_id))); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Applications/Todpole/Web/auth.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Hold on... 7 | 8 | 9 | 10 | 11 | 12 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Applications/Todpole/Web/css/images/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudXNS/mss/3c7af06ef22f49b78f7f18a3ac69ef785ad7591f/Applications/Todpole/Web/css/images/github.png -------------------------------------------------------------------------------- /Applications/Todpole/Web/css/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudXNS/mss/3c7af06ef22f49b78f7f18a3ac69ef785ad7591f/Applications/Todpole/Web/css/images/logo.png -------------------------------------------------------------------------------- /Applications/Todpole/Web/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudXNS/mss/3c7af06ef22f49b78f7f18a3ac69ef785ad7591f/Applications/Todpole/Web/favicon.ico -------------------------------------------------------------------------------- /Applications/Todpole/Web/images/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudXNS/mss/3c7af06ef22f49b78f7f18a3ac69ef785ad7591f/Applications/Todpole/Web/images/apple-touch-icon.png -------------------------------------------------------------------------------- /Applications/Todpole/Web/images/fb-image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudXNS/mss/3c7af06ef22f49b78f7f18a3ac69ef785ad7591f/Applications/Todpole/Web/images/fb-image.jpg -------------------------------------------------------------------------------- /Applications/Todpole/Web/images/workerman-todpole-browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudXNS/mss/3c7af06ef22f49b78f7f18a3ac69ef785ad7591f/Applications/Todpole/Web/images/workerman-todpole-browser.png -------------------------------------------------------------------------------- /Applications/Todpole/Web/js/Arrow.js: -------------------------------------------------------------------------------- 1 | var Arrow = function(tadpole, camera) { 2 | var arrow = this; 3 | 4 | this.x = 0; 5 | this.y = 0; 6 | 7 | this.tadpole = tadpole; 8 | this.camera = camera; 9 | 10 | this.angle = 0; 11 | this.distance = 10; 12 | 13 | this.opacity = 1; 14 | 15 | this.update = function() { 16 | arrow.angle = Math.atan2(tadpole.y - arrow.camera.y, tadpole.x - arrow.camera.x); 17 | }; 18 | 19 | this.draw = function(context, canvas) { 20 | var cameraBounds = arrow.camera.getBounds(); 21 | 22 | if( arrow.tadpole.x < cameraBounds[0].x || 23 | arrow.tadpole.y < cameraBounds[0].y || 24 | arrow.tadpole.x > cameraBounds[1].x || 25 | arrow.tadpole.y > cameraBounds[1].y ) { 26 | 27 | var size = 4; 28 | 29 | var arrowDistance = 100; 30 | 31 | var angle = arrow.angle; 32 | var w = (canvas.width/2) - 10; 33 | var h = (canvas.height/2) - 10; 34 | var aa = Math.atan(h / w); 35 | var ss = Math.cos(angle); 36 | var cc = Math.sin(angle); 37 | 38 | if((Math.abs(angle) + aa) % Math.PI / 2 < aa) { 39 | arrowDistance = w / Math.abs(ss); 40 | } else { 41 | arrowDistance = h / Math.abs(cc); 42 | } 43 | 44 | var x = (canvas.width/2) + Math.cos(arrow.angle) * arrowDistance; 45 | var y = (canvas.height/2) + Math.sin(arrow.angle) * arrowDistance; 46 | 47 | var point = calcPoint(x, y, this.angle, 2, size); 48 | var side1 = calcPoint(x, y, this.angle, 1.5, size); 49 | var side2 = calcPoint(x, y, this.angle, 0.5, size); 50 | 51 | // Draw arrow 52 | context.fillStyle = 'rgba(255,255,255,'+arrow.opacity+')'; 53 | context.beginPath(); 54 | context.moveTo(point.x, point.y); 55 | context.lineTo(side1.x, side1.y); 56 | context.lineTo(side2.x, side2.y) 57 | context.closePath(); 58 | context.fill(); 59 | } 60 | }; 61 | 62 | var calcPoint = function(x, y, angle, angleMultiplier, length) { 63 | return { 64 | x: x + Math.cos(angle + Math.PI * angleMultiplier) * length, 65 | y: y + Math.sin(angle + Math.PI * angleMultiplier) * length 66 | } 67 | }; 68 | } 69 | -------------------------------------------------------------------------------- /Applications/Todpole/Web/js/Camera.js: -------------------------------------------------------------------------------- 1 | var Camera = function(aCanvas, aContext, x, y) { 2 | var camera = this; 3 | 4 | var canvas = aCanvas; 5 | var context = aContext; 6 | 7 | this.x = x; 8 | this.y = y; 9 | 10 | this.minZoom = 1.3; 11 | this.maxZoom = 1.8; 12 | this.zoom = this.minZoom; 13 | 14 | var backgroundColor = Math.random()*360; 15 | 16 | this.setupContext = function() { 17 | var translateX = canvas.width / 2 - camera.x * camera.zoom; 18 | var translateY = canvas.height / 2 - camera.y * camera.zoom; 19 | 20 | // Reset transform matrix 21 | context.setTransform(1,0,0,1,0,0); 22 | context.fillStyle = 'hsl('+backgroundColor+',50%,10%)'; 23 | context.fillRect(0,0,canvas.width, canvas.height); 24 | 25 | context.translate(translateX, translateY); 26 | context.scale(camera.zoom, camera.zoom); 27 | 28 | if(debug) { 29 | drawDebug(); 30 | } 31 | }; 32 | 33 | this.update = function(model) { 34 | backgroundColor += 0.08; 35 | backgroundColor = backgroundColor > 360 ? 0 : backgroundColor; 36 | 37 | var targetZoom = (model.camera.maxZoom + (model.camera.minZoom - model.camera.maxZoom) * Math.min(model.userTadpole.momentum, model.userTadpole.maxMomentum) / model.userTadpole.maxMomentum); 38 | model.camera.zoom += (targetZoom - model.camera.zoom) / 60; 39 | 40 | var delta = { 41 | x: (model.userTadpole.x - model.camera.x) / 30, 42 | y: (model.userTadpole.y - model.camera.y) / 30 43 | } 44 | 45 | if(Math.abs(delta.x) + Math.abs(delta.y) > 0.1) { 46 | model.camera.x += delta.x; 47 | model.camera.y += delta.y; 48 | 49 | for(var i = 0, len = model.waterParticles.length; i < len; i++) { 50 | var wp = model.waterParticles[i]; 51 | wp.x -= (wp.z - 1) * delta.x; 52 | wp.y -= (wp.z - 1) * delta.y; 53 | } 54 | } 55 | }; 56 | 57 | // Gets bounds of current zoom level of current position 58 | this.getBounds = function() { 59 | return [ 60 | {x: camera.x - canvas.width / 2 / camera.zoom, y: camera.y - canvas.height / 2 / camera.zoom}, 61 | {x: camera.x + canvas.width / 2 / camera.zoom, y: camera.y + canvas.height / 2 / camera.zoom} 62 | ]; 63 | }; 64 | 65 | // Gets bounds of minimum zoom level of current position 66 | this.getOuterBounds = function() { 67 | return [ 68 | {x: camera.x - canvas.width / 2 / camera.minZoom, y: camera.y - canvas.height / 2 / camera.minZoom}, 69 | {x: camera.x + canvas.width / 2 / camera.minZoom, y: camera.y + canvas.height / 2 / camera.minZoom} 70 | ]; 71 | }; 72 | 73 | // Gets bounds of maximum zoom level of current position 74 | this.getInnerBounds = function() { 75 | return [ 76 | {x: camera.x - canvas.width / 2 / camera.maxZoom, y: camera.y - canvas.height / 2 / camera.maxZoom}, 77 | {x: camera.x + canvas.width / 2 / camera.maxZoom, y: camera.y + canvas.height / 2 / camera.maxZoom} 78 | ]; 79 | }; 80 | 81 | this.startUILayer = function() { 82 | context.setTransform(1,0,0,1,0,0); 83 | } 84 | 85 | var debugBounds = function(bounds, text) { 86 | context.strokeStyle = '#fff'; 87 | context.beginPath(); 88 | context.moveTo(bounds[0].x, bounds[0].y); 89 | context.lineTo(bounds[0].x, bounds[1].y); 90 | context.lineTo(bounds[1].x, bounds[1].y); 91 | context.lineTo(bounds[1].x, bounds[0].y); 92 | context.closePath(); 93 | context.stroke(); 94 | context.fillText(text, bounds[0].x + 10, bounds[0].y + 10); 95 | }; 96 | 97 | var drawDebug = function() { 98 | debugBounds(camera.getInnerBounds(), 'Maximum zoom camera bounds'); 99 | debugBounds(camera.getOuterBounds(), 'Minimum zoom camera bounds'); 100 | debugBounds(camera.getBounds(), 'Current zoom camera bounds'); 101 | }; 102 | }; -------------------------------------------------------------------------------- /Applications/Todpole/Web/js/Cookie.js: -------------------------------------------------------------------------------- 1 | jQuery.cookie = function(name, value, options) { 2 | if (typeof value != 'undefined') { 3 | options = options || {}; 4 | if (value === null) { 5 | value = ''; 6 | options = $.extend({}, options); 7 | options.expires = -1; 8 | } 9 | var expires = ''; 10 | if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) { 11 | var date; 12 | if (typeof options.expires == 'number') { 13 | date = new Date(); 14 | date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000)); 15 | } else { 16 | date = options.expires; 17 | } 18 | expires = '; expires=' + date.toUTCString(); 19 | } 20 | var path = options.path ? '; path=' + (options.path) : ''; 21 | var domain = options.domain ? '; domain=' + (options.domain) : ''; 22 | var secure = options.secure ? '; secure' : ''; 23 | document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join(''); 24 | } else { 25 | var cookieValue = null; 26 | if (document.cookie && document.cookie != '') { 27 | var cookies = document.cookie.split(';'); 28 | for (var i = 0; i < cookies.length; i++) { 29 | var cookie = jQuery.trim(cookies[i]); 30 | if (cookie.substring(0, name.length + 1) == (name + '=')) { 31 | cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); 32 | break; 33 | } 34 | } 35 | } 36 | return cookieValue; 37 | } 38 | }; -------------------------------------------------------------------------------- /Applications/Todpole/Web/js/Keys.js: -------------------------------------------------------------------------------- 1 | var keys = { 2 | esc: 27, 3 | enter: 13, 4 | space: 32, 5 | up: 38, 6 | down: 40, 7 | left:37, 8 | right:39 9 | }; 10 | -------------------------------------------------------------------------------- /Applications/Todpole/Web/js/Message.js: -------------------------------------------------------------------------------- 1 | var Message = function(msg) { 2 | var message = this; 3 | 4 | this.age = 1; 5 | this.maxAge = 300; 6 | 7 | this.message = msg; 8 | 9 | this.update = function() { 10 | this.age++; 11 | } 12 | 13 | this.draw = function(context,x,y,i) { 14 | var fontsize = 8; 15 | context.font = fontsize + "px 'proxima-nova-1','proxima-nova-2', arial, sans-serif"; 16 | context.textBaseline = 'hanging'; 17 | 18 | var paddingH = 3; 19 | var paddingW = 6; 20 | 21 | var messageBox = { 22 | width: context.measureText(message.message).width + paddingW * 2, 23 | height: fontsize + paddingH * 2, 24 | x: x, 25 | y: (y - i * (fontsize + paddingH * 2 +1))-20 26 | } 27 | 28 | var fadeDuration = 20; 29 | 30 | var opacity = (message.maxAge - message.age) / fadeDuration; 31 | opacity = opacity < 1 ? opacity : 1; 32 | 33 | context.fillStyle = 'rgba(255,255,255,'+opacity/20+')'; 34 | drawRoundedRectangle(context, messageBox.x, messageBox.y, messageBox.width, messageBox.height, 10); 35 | context.fillStyle = 'rgba(255,255,255,'+opacity+')'; 36 | context.fillText(message.message, messageBox.x + paddingW, messageBox.y + paddingH, 100); 37 | } 38 | 39 | var drawRoundedRectangle = function(ctx,x,y,w,h,r) { 40 | var r = r / 2; 41 | ctx.beginPath(); 42 | ctx.moveTo(x, y+r); 43 | ctx.lineTo(x, y+h-r); 44 | ctx.quadraticCurveTo(x, y+h, x+r, y+h); 45 | ctx.lineTo(x+w-r, y+h); 46 | ctx.quadraticCurveTo(x+w, y+h, x+w, y+h-r); 47 | ctx.lineTo(x+w, y+r); 48 | ctx.quadraticCurveTo(x+w, y, x+w-r, y); 49 | ctx.lineTo(x+r, y); 50 | ctx.quadraticCurveTo(x, y, x, y+r); 51 | ctx.closePath(); 52 | ctx.fill(); 53 | } 54 | } -------------------------------------------------------------------------------- /Applications/Todpole/Web/js/Model.js: -------------------------------------------------------------------------------- 1 | var Model = function() { 2 | this.tadpoles = {}; 3 | this.userTadpole; 4 | this.camera; 5 | this.settings; 6 | } -------------------------------------------------------------------------------- /Applications/Todpole/Web/js/Settings.js: -------------------------------------------------------------------------------- 1 | // 此文件下载者不用更改,兼容其他域名使用 2 | var Settings = function() { 3 | // 如果是workerman.net phpgame.cn域名 则采用多个接入端随机负载均衡 4 | var domain_arr = ['workerman.net', 'phpgame.cn','www.workerman.net', 'www.phpgame.cn']; 5 | if(0 <= $.inArray(document.domain, domain_arr)) 6 | { 7 | this.socketServer = 'ws://'+domain_arr[Math.floor(Math.random() * domain_arr.length + 1)-1]+':8585'; 8 | } 9 | else 10 | { 11 | // 运行在其它域名上 12 | this.socketServer = 'ws://'+document.domain+':8585'; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Applications/Todpole/Web/js/TadpoleTail.js: -------------------------------------------------------------------------------- 1 | var TadpoleTail = function(tadpole) { 2 | var tail = this; 3 | tail.joints = []; 4 | 5 | var tadpole = tadpole; 6 | var jointSpacing = 1.4; 7 | var animationRate = 0; 8 | 9 | 10 | tail.update = function() { 11 | animationRate += (.2 + tadpole.momentum / 10); 12 | 13 | for(var i = 0, len = tail.joints.length; i < len; i++) { 14 | var tailJoint = tail.joints[i]; 15 | var parentJoint = tail.joints[i-1] || tadpole; 16 | var anglediff = (parentJoint.angle - tailJoint.angle); 17 | 18 | while(anglediff < -Math.PI) { 19 | anglediff += Math.PI * 2; 20 | } 21 | while(anglediff > Math.PI) { 22 | anglediff -= Math.PI * 2; 23 | } 24 | 25 | tailJoint.angle += anglediff * (jointSpacing * 3 + (Math.min(tadpole.momentum / 2, Math.PI * 1.8))) / 8; 26 | tailJoint.angle += Math.cos(animationRate - (i / 3)) * ((tadpole.momentum + .3) / 40); 27 | 28 | if(i == 0) { 29 | tailJoint.x = parentJoint.x + Math.cos(tailJoint.angle + Math.PI) * 5; 30 | tailJoint.y = parentJoint.y + Math.sin(tailJoint.angle + Math.PI) * 5; 31 | } else { 32 | tailJoint.x = parentJoint.x + Math.cos(tailJoint.angle + Math.PI) * jointSpacing; 33 | tailJoint.y = parentJoint.y + Math.sin(tailJoint.angle + Math.PI) * jointSpacing; 34 | } 35 | } 36 | }; 37 | 38 | tail.draw = function(context) { 39 | var path = [[],[]]; 40 | 41 | for(var i = 0, len = tail.joints.length; i < len; i++) { 42 | var tailJoint = tail.joints[i]; 43 | 44 | var falloff = (tail.joints.length - i) / tail.joints.length; 45 | var jointSize = (tadpole.size - 1.8) * falloff; 46 | 47 | var x1 = tailJoint.x + Math.cos(tailJoint.angle + Math.PI * 1.5) * jointSize; 48 | var y1 = tailJoint.y + Math.sin(tailJoint.angle + Math.PI * 1.5) * jointSize; 49 | 50 | var x2 = tailJoint.x + Math.cos(tailJoint.angle + Math.PI / 2) * jointSize; 51 | var y2 = tailJoint.y + Math.sin(tailJoint.angle + Math.PI / 2) * jointSize; 52 | 53 | path[0].push({x: x1, y: y1}); 54 | path[1].push({x: x2, y: y2}); 55 | } 56 | 57 | for(var i = 0; i < path[0].length; i++) { 58 | context.lineTo(path[0][i].x, path[0][i].y); 59 | } 60 | path[1].reverse(); 61 | for(var i = 0; i < path[1].length; i++) { 62 | context.lineTo(path[1][i].x, path[1][i].y); 63 | } 64 | }; 65 | 66 | (function() { 67 | for(var i = 0; i < 15; i++) { 68 | tail.joints.push({ 69 | x: 0, 70 | y: 0, 71 | angle: Math.PI*2, 72 | }) 73 | } 74 | })(); 75 | } -------------------------------------------------------------------------------- /Applications/Todpole/Web/js/WaterParticle.js: -------------------------------------------------------------------------------- 1 | var WaterParticle = function() { 2 | var wp = this; 3 | 4 | wp.x = 0; 5 | wp.y = 0; 6 | wp.z = Math.random() * 1 + 0.3; 7 | wp.size = 1.2; 8 | wp.opacity = Math.random() * 0.8 + 0.1; 9 | 10 | wp.update = function(bounds) { 11 | if(wp.x == 0 || wp.y == 0) { 12 | wp.x = Math.random() * (bounds[1].x - bounds[0].x) + bounds[0].x; 13 | wp.y = Math.random() * (bounds[1].y - bounds[0].y) + bounds[0].y; 14 | } 15 | 16 | // Wrap around screen 17 | wp.x = wp.x < bounds[0].x ? bounds[1].x : wp.x; 18 | wp.y = wp.y < bounds[0].y ? bounds[1].y : wp.y; 19 | wp.x = wp.x > bounds[1].x ? bounds[0].x : wp.x; 20 | wp.y = wp.y > bounds[1].y ? bounds[0].y : wp.y; 21 | }; 22 | 23 | wp.draw = function(context) { 24 | // Draw circle 25 | context.fillStyle = 'rgba(226,219,226,'+wp.opacity+')'; 26 | //context.fillStyle = '#fff'; 27 | context.beginPath(); 28 | context.arc(wp.x, wp.y, this.z * this.size, 0, Math.PI*2, true); 29 | context.closePath(); 30 | context.fill(); 31 | }; 32 | } 33 | -------------------------------------------------------------------------------- /Applications/Todpole/Web/js/WebSocketService.js: -------------------------------------------------------------------------------- 1 | var WebSocketService = function(model, webSocket) { 2 | var webSocketService = this; 3 | 4 | var webSocket = webSocket; 5 | var model = model; 6 | 7 | this.hasConnection = false; 8 | 9 | this.welcomeHandler = function(data) { 10 | webSocketService.hasConnection = true; 11 | 12 | model.userTadpole.id = data.id; 13 | model.tadpoles[data.id] = model.tadpoles[-1]; 14 | delete model.tadpoles[-1]; 15 | 16 | $('#chat').initChat(); 17 | if($.cookie('todpole_name')) { 18 | webSocketService.sendMessage('name:'+$.cookie('todpole_name')); 19 | } 20 | }; 21 | 22 | this.updateHandler = function(data) { 23 | var newtp = false; 24 | 25 | if(!model.tadpoles[data.id]) { 26 | newtp = true; 27 | model.tadpoles[data.id] = new Tadpole(); 28 | model.arrows[data.id] = new Arrow(model.tadpoles[data.id], model.camera); 29 | } 30 | 31 | var tadpole = model.tadpoles[data.id]; 32 | 33 | if(tadpole.id == model.userTadpole.id) { 34 | tadpole.name = data.name; 35 | return; 36 | } else { 37 | tadpole.name = data.name; 38 | } 39 | 40 | if(newtp) { 41 | tadpole.x = data.x; 42 | tadpole.y = data.y; 43 | } else { 44 | tadpole.targetX = data.x; 45 | tadpole.targetY = data.y; 46 | } 47 | 48 | tadpole.angle = data.angle; 49 | tadpole.momentum = data.momentum; 50 | 51 | tadpole.timeSinceLastServerUpdate = 0; 52 | } 53 | 54 | this.messageHandler = function(data) { 55 | var tadpole = model.tadpoles[data.id]; 56 | if(!tadpole) { 57 | return; 58 | } 59 | tadpole.timeSinceLastServerUpdate = 0; 60 | tadpole.messages.push(new Message(data.message)); 61 | } 62 | 63 | this.closedHandler = function(data) { 64 | if(model.tadpoles[data.id]) { 65 | delete model.tadpoles[data.id]; 66 | delete model.arrows[data.id]; 67 | } 68 | } 69 | 70 | this.redirectHandler = function(data) { 71 | if (data.url) { 72 | if (authWindow) { 73 | authWindow.document.location = data.url; 74 | } else { 75 | document.location = data.url; 76 | } 77 | } 78 | } 79 | 80 | this.processMessage = function(data) { 81 | var fn = webSocketService[data.type + 'Handler']; 82 | if (fn) { 83 | fn(data); 84 | } 85 | } 86 | 87 | this.connectionClosed = function() { 88 | webSocketService.hasConnection = false; 89 | $('#cant-connect').fadeIn(300); 90 | }; 91 | 92 | this.sendUpdate = function(tadpole) { 93 | var sendObj = { 94 | type: 'update', 95 | x: tadpole.x.toFixed(1), 96 | y: tadpole.y.toFixed(1), 97 | angle: tadpole.angle.toFixed(3), 98 | momentum: tadpole.momentum.toFixed(3) 99 | }; 100 | 101 | if(tadpole.name) { 102 | sendObj['name'] = tadpole.name; 103 | } 104 | 105 | webSocket.send(JSON.stringify(sendObj)); 106 | } 107 | 108 | this.sendMessage = function(msg) { 109 | var regexp = /name: ?(.+)/i; 110 | if(regexp.test(msg)) { 111 | model.userTadpole.name = msg.match(regexp)[1]; 112 | $.cookie('todpole_name', model.userTadpole.name, {expires:14}); 113 | return; 114 | } 115 | 116 | var sendObj = { 117 | type: 'message', 118 | message: msg 119 | }; 120 | 121 | webSocket.send(JSON.stringify(sendObj)); 122 | } 123 | 124 | this.authorize = function(token,verifier) { 125 | var sendObj = { 126 | type: 'authorize', 127 | token: token, 128 | verifier: verifier 129 | }; 130 | 131 | webSocket.send(JSON.stringify(sendObj)); 132 | } 133 | } -------------------------------------------------------------------------------- /Applications/Todpole/Web/js/formControls.js: -------------------------------------------------------------------------------- 1 | // Settings controls 2 | 3 | (function($){ 4 | 5 | $.fn.initChat = function() { 6 | var input = $(this); 7 | var chatText = $("#chatText"); 8 | var hidden = true; 9 | var messageHistory = []; 10 | var messagePointer = -1; 11 | 12 | var closechat = function() { 13 | hidden = true; 14 | input.css("opacity","0"); 15 | messagePointer = messageHistory.length; 16 | input.val(''); 17 | chatText.text('') 18 | } 19 | 20 | var updateDimensions = function(){ 21 | chatText.text(input.val()); 22 | var width = chatText.width() + 30; 23 | input.css({ 24 | width: width, 25 | marginLeft: (width/2)*-1 26 | }); 27 | }; 28 | 29 | input.blur(function(e) { 30 | setTimeout(function(){input.focus()}, 0.1); 31 | }); 32 | input.keydown(function(e){ 33 | if(input.val().length > 0) { 34 | //set timeout because event occurs before text is entered 35 | setTimeout(updateDimensions,0.1); 36 | input.css("opacity","1"); 37 | } else { 38 | closechat(); 39 | } 40 | 41 | if(!hidden) { 42 | 43 | e.stopPropagation(); 44 | if(messageHistory.length > 0) { 45 | if(e.keyCode == keys.up) 46 | { 47 | if(messagePointer > 0) 48 | { 49 | messagePointer--; 50 | input.val(messageHistory[messagePointer]); 51 | } 52 | } 53 | else if(e.keyCode == keys.down) 54 | { 55 | if(messagePointer < messageHistory.length-1) 56 | { 57 | messagePointer++; 58 | input.val(messageHistory[messagePointer]); 59 | } 60 | else 61 | { 62 | closechat(); 63 | return; 64 | } 65 | } 66 | } 67 | } 68 | }); 69 | input.keyup(function(e) { 70 | 71 | var k = e.keyCode; 72 | if(input.val().length >= 45) 73 | { 74 | input.val(input.val().substr(0,45)); 75 | } 76 | 77 | if(input.val().length > 0) { 78 | updateDimensions(); 79 | input.css("opacity","1"); 80 | hidden = false; 81 | } else { 82 | closechat(); 83 | } 84 | if(!hidden) { 85 | if(k == keys.esc || k == keys.enter || (k == keys.space && input.val().length > 35)) { 86 | if(k != keys.esc && input.val().length > 0) { 87 | messageHistory.push(input.val()); 88 | messagePointer = messageHistory.length; 89 | app.sendMessage(input.val()); 90 | } 91 | closechat(); 92 | } 93 | 94 | e.stopPropagation(); 95 | 96 | } 97 | 98 | }); 99 | 100 | input.focus(); 101 | } 102 | 103 | $(function() { 104 | //$('#chat').initChat(); 105 | }); 106 | })(jQuery); 107 | -------------------------------------------------------------------------------- /Applications/Todpole/Web/js/frogMode.js: -------------------------------------------------------------------------------- 1 | var frogMode = function() { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /Applications/Todpole/Web/js/lib/parseUri.js: -------------------------------------------------------------------------------- 1 | // parseUri 1.2.2 2 | // (c) Steven Levithan 3 | // MIT License 4 | 5 | function parseUri (str) { 6 | var o = parseUri.options, 7 | m = o.parser[o.strictMode ? "strict" : "loose"].exec(str), 8 | uri = {}, 9 | i = 14; 10 | 11 | while (i--) uri[o.key[i]] = m[i] || ""; 12 | 13 | uri[o.q.name] = {}; 14 | uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) { 15 | if ($1) uri[o.q.name][$1] = $2; 16 | }); 17 | 18 | return uri; 19 | }; 20 | 21 | parseUri.options = { 22 | strictMode: false, 23 | key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"], 24 | q: { 25 | name: "queryKey", 26 | parser: /(?:^|&)([^&=]*)=?([^&]*)/g 27 | }, 28 | parser: { 29 | strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/, 30 | loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ 31 | } 32 | }; -------------------------------------------------------------------------------- /Applications/Todpole/Web/js/main.js: -------------------------------------------------------------------------------- 1 | var settings = new Settings(); 2 | 3 | var debug = false; 4 | var isStatsOn = false; 5 | 6 | var authWindow; 7 | 8 | var app; 9 | var runLoop = function() { 10 | app.update(); 11 | app.draw(); 12 | } 13 | var initApp = function() { 14 | if (app!=null) { return; } 15 | app = new App(settings, document.getElementById('canvas')); 16 | 17 | window.addEventListener('resize', app.resize, false); 18 | 19 | document.addEventListener('mousemove', app.mousemove, false); 20 | document.addEventListener('mousedown', app.mousedown, false); 21 | document.addEventListener('mouseup', app.mouseup, false); 22 | 23 | document.addEventListener('touchstart', app.touchstart, false); 24 | document.addEventListener('touchend', app.touchend, false); 25 | document.addEventListener('touchcancel', app.touchend, false); 26 | document.addEventListener('touchmove', app.touchmove, false); 27 | 28 | document.addEventListener('keydown', app.keydown, false); 29 | document.addEventListener('keyup', app.keyup, false); 30 | 31 | setInterval(runLoop,30); 32 | } 33 | 34 | var forceInit = function() { 35 | initApp() 36 | document.getElementById('unsupported-browser').style.display = "none"; 37 | return false; 38 | } 39 | 40 | if(Modernizr.canvas && Modernizr.websockets) { 41 | initApp(); 42 | } else { 43 | document.getElementById('unsupported-browser').style.display = "block"; 44 | document.getElementById('force-init-button').addEventListener('click', forceInit, false); 45 | } 46 | 47 | var addStats = function() { 48 | if (isStatsOn) { return; } 49 | // Draw fps 50 | var stats = new Stats(); 51 | document.getElementById('fps').appendChild(stats.domElement); 52 | 53 | setInterval(function () { 54 | stats.update(); 55 | }, 1000/60); 56 | 57 | // Array Remove - By John Resig (MIT Licensed) 58 | Array.remove = function(array, from, to) { 59 | var rest = array.slice((to || from) + 1 || array.length); 60 | array.length = from < 0 ? array.length + from : from; 61 | return array.push.apply(array, rest); 62 | }; 63 | isStatsOn = true; 64 | } 65 | 66 | //document.addEventListener('keydown',function(e) { 67 | // if(e.which == 27) { 68 | // addStats(); 69 | // } 70 | //}) 71 | 72 | if(debug) { addStats(); } 73 | 74 | $(function() { 75 | $('a[rel=external]').click(function(e) { 76 | e.preventDefault(); 77 | window.open($(this).attr('href')); 78 | }); 79 | }); 80 | 81 | document.body.onselectstart = function() { return false; } 82 | -------------------------------------------------------------------------------- /Applications/Todpole/start-bak.php: -------------------------------------------------------------------------------- 1 | name = 'TodpoleGateway'; 16 | // 开启的进程数,建议与cpu核数相同 17 | $gateway->count = 4; 18 | // 分布式部署时请设置成内网ip(非127.0.0.1) 19 | $gateway->lanIp = '127.0.0.1'; 20 | // 内部通讯起始端口,假如$gateway->count=4,起始端口为4000 21 | // 则一般会使用4001 4002 4003 4004 4个端口作为内部通讯端口 22 | $gateway->startPort = 4000; 23 | // 心跳间隔 24 | $gateway->pingInterval = 10; 25 | // 心跳数据 26 | $gateway->pingData = '{"type":"ping"}'; 27 | 28 | /* 29 | // 当客户端连接上来时,设置连接的onWebSocketConnect,即在websocket握手时的回调 30 | $gateway->onConnect = function($connection) 31 | { 32 | $connection->onWebSocketConnect = function($connection , $http_header) 33 | { 34 | // 可以在这里判断连接来源是否合法,不合法就关掉连接 35 | // $_SERVER['HTTP_ORIGIN']标识来自哪个站点的页面发起的websocket链接 36 | if($_SERVER['HTTP_ORIGIN'] != 'http://kedou.workerman.net') 37 | { 38 | $connection->close(); 39 | } 40 | // onWebSocketConnect 里面$_GET $_SERVER是可用的 41 | // var_dump($_GET, $_SERVER); 42 | }; 43 | }; 44 | */ 45 | 46 | // bussinessWorker 进程 47 | $worker = new BusinessWorker(); 48 | // worker名称 49 | $worker->name = 'TodpoleBusinessWorker'; 50 | // bussinessWorker进程数量 51 | $worker->count = 4; 52 | 53 | 54 | // WebServer 55 | $web = new WebServer("http://0.0.0.0:8686"); 56 | // WebServer数量 57 | $web->count = 2; 58 | // 设置站点根目录 59 | $web->addRoot('www.your_domain.com', __DIR__.'/Web'); 60 | 61 | 62 | // 如果不是在根目录启动,则运行runAll方法 63 | if(!defined('GLOBAL_START')) 64 | { 65 | Worker::runAll(); 66 | } 67 | -------------------------------------------------------------------------------- /Applications/config.php: -------------------------------------------------------------------------------- 1 | 'email', //redis的key 6 | 'Sms_redis_key' => 'sms', //redis的key 7 | 'redis_ip' => '127.0.0.1', //redis的ip 8 | 'redis_port' => 6379, //redis的port 9 | 'redis_db' => 0, //redis的db 10 | 'requirepass' => 'password', //redis的密码 11 | 12 | //sms短信 13 | 'sms_apikey' => 'apikey', //云片网的apikey 14 | 'sms_send_url' => 'http://yunpian.com/v1/sms/send.json', //云片网api地址 15 | 16 | 'mail_host' => 'mail.com', //邮件服务器 17 | 'mail_port' => 25, //邮件服务器端口 18 | 'mail_password' => 'password',//发件人邮箱密码 19 | 'mail_charset' => 'UTF-8', 20 | 'mail_encoding' => 'base64', 21 | 'mail_sender' => 'send@mail.com',//发件人邮箱用户名 22 | 'mail_smtpdebug' => 0, 23 | 'mail_smtpauth' => true, 24 | 25 | 'db_ip' => '127.0.0.1', //数据库ip 26 | 'db_username' => 'user',//数据库连接用户名 27 | 'db_password' => 'password',//数据库连接密码 28 | 'db' => 'db', //数据库名称 29 | ); -------------------------------------------------------------------------------- /GatewayWorker/Lib/Context.php: -------------------------------------------------------------------------------- 1 | 6 | */ 7 | class Db 8 | { 9 | /** 10 | * 实例数组 11 | * @var array 12 | */ 13 | protected static $instance = array(); 14 | 15 | /** 16 | * 获取实例 17 | * @param string $config_name 18 | * @throws \Exception 19 | */ 20 | public static function instance($config_name) 21 | { 22 | if(!isset(\Config\Db::$$config_name)) 23 | { 24 | echo "\\Config\\Db::$config_name not set\n"; 25 | throw new \Exception("\\Config\\Db::$config_name not set\n"); 26 | } 27 | 28 | if(empty(self::$instance[$config_name])) 29 | { 30 | $config = \Config\Db::$$config_name; 31 | self::$instance[$config_name] = new \GatewayWorker\Lib\DbConnection($config['host'], $config['port'], $config['user'], $config['password'], $config['dbname']); 32 | } 33 | return self::$instance[$config_name]; 34 | } 35 | 36 | /** 37 | * 关闭数据库实例 38 | * @param string $config_name 39 | */ 40 | public static function close($config_name) 41 | { 42 | if(isset(self::$instance[$config_name])) 43 | { 44 | self::$instance[$config_name]->closeConnection(); 45 | self::$instance[$config_name] = null; 46 | } 47 | } 48 | 49 | /** 50 | * 关闭所有数据库实例 51 | */ 52 | public static function closeAll() 53 | { 54 | foreach(self::$instance as $connection) 55 | { 56 | $connection->closeConnection(); 57 | } 58 | self::$instance = array(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /GatewayWorker/Lib/Lock.php: -------------------------------------------------------------------------------- 1 | 7 | */ 8 | class Store 9 | { 10 | /** 11 | * 实例数组 12 | * @var array 13 | */ 14 | protected static $instance = array(); 15 | 16 | /** 17 | * 获取实例 18 | * @param string $config_name 19 | * @throws \Exception 20 | */ 21 | public static function instance($config_name) 22 | { 23 | // memcached 驱动 24 | if(\Config\Store::$driver == \Config\Store::DRIVER_MC) 25 | { 26 | if(!isset(\Config\Store::$$config_name)) 27 | { 28 | echo "\\Config\\Store::$config_name not set\n"; 29 | throw new \Exception("\\Config\\Store::$config_name not set\n"); 30 | } 31 | 32 | if(!isset(self::$instance[$config_name])) 33 | { 34 | if(extension_loaded('Memcached')) 35 | { 36 | self::$instance[$config_name] = new \Memcached; 37 | } 38 | elseif(extension_loaded('Memcache')) 39 | { 40 | self::$instance[$config_name] = new \Memcache; 41 | } 42 | else 43 | { 44 | sleep(2); 45 | exit("extension memcached is not installed\n"); 46 | } 47 | foreach(\Config\Store::$$config_name as $address) 48 | { 49 | list($ip, $port) = explode(':', $address); 50 | self::$instance[$config_name] ->addServer($ip, $port); 51 | } 52 | } 53 | return self::$instance[$config_name]; 54 | } 55 | // 文件驱动 56 | else 57 | { 58 | if(!isset(self::$instance[$config_name])) 59 | { 60 | // 关闭opcache 61 | ini_set('opcache.enable', false); 62 | self::$instance[$config_name] = new \GatewayWorker\Lib\StoreDriver\File($config_name); 63 | } 64 | return self::$instance[$config_name]; 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /GatewayWorker/Lib/StoreDriver/File.php: -------------------------------------------------------------------------------- 1 | 9 | * 10 | */ 11 | 12 | class File 13 | { 14 | // 为了避免频繁读取磁盘,增加了缓存机制 15 | protected $dataCache = array(); 16 | // 上次缓存时间 17 | protected $lastCacheTime = 0; 18 | // 保存数据的文件 19 | protected $dataFile = ''; 20 | // 打开文件的句柄 21 | protected $dataFileHandle = null; 22 | 23 | /** 24 | * 构造函数 25 | * @param 配置名 $config_name 26 | */ 27 | public function __construct($config_name) 28 | { 29 | $this->dataFile = \Config\Store::$storePath . "/$config_name.store.cache.php"; 30 | if(!is_dir(\Config\Store::$storePath) && !@mkdir(\Config\Store::$storePath, 0777, true)) 31 | { 32 | // 可能目录已经被其它进程创建 33 | clearstatcache(); 34 | if(!is_dir(\Config\Store::$storePath)) 35 | { 36 | // 避免狂刷日志 37 | sleep(1); 38 | throw new \Exception('cant not mkdir('.\Config\Store::$storePath.')'); 39 | } 40 | } 41 | if(!is_file($this->dataFile)) 42 | { 43 | touch($this->dataFile); 44 | } 45 | $this->dataFileHandle = fopen(__FILE__, 'r'); 46 | if(!$this->dataFileHandle) 47 | { 48 | throw new \Exception("can not fopen($this->dataFile, 'r')"); 49 | } 50 | } 51 | 52 | /** 53 | * 设置 54 | * @param string $key 55 | * @param mixed $value 56 | * @param int $ttl 57 | * @return number 58 | */ 59 | public function set($key, $value, $ttl = 0) 60 | { 61 | flock($this->dataFileHandle, LOCK_EX); 62 | $this->readDataFromDisk(); 63 | $this->dataCache[$key] = $value; 64 | $ret = $this->writeToDisk(); 65 | flock($this->dataFileHandle, LOCK_UN); 66 | return $ret; 67 | } 68 | 69 | /** 70 | * 读取 71 | * @param string $key 72 | * @param bool $use_cache 73 | * @return Ambigous 74 | */ 75 | public function get($key, $use_cache = true) 76 | { 77 | flock($this->dataFileHandle, LOCK_EX); 78 | $this->readDataFromDisk(); 79 | flock($this->dataFileHandle, LOCK_UN); 80 | return isset($this->dataCache[$key]) ? $this->dataCache[$key] : null; 81 | } 82 | 83 | /** 84 | * 删除 85 | * @param string $key 86 | * @return number 87 | */ 88 | public function delete($key) 89 | { 90 | flock($this->dataFileHandle, LOCK_EX); 91 | $this->readDataFromDisk(); 92 | unset($this->dataCache[$key]); 93 | $ret = $this->writeToDisk(); 94 | flock($this->dataFileHandle, LOCK_UN); 95 | return $ret; 96 | } 97 | 98 | /** 99 | * 自增 100 | * @param string $key 101 | * @return boolean|multitype: 102 | */ 103 | public function increment($key) 104 | { 105 | flock($this->dataFileHandle, LOCK_EX); 106 | $this->readDataFromDisk(); 107 | if(!isset($this->dataCache[$key])) 108 | { 109 | flock($this->dataFileHandle, LOCK_UN); 110 | return false; 111 | } 112 | $this->dataCache[$key] ++; 113 | $this->writeToDisk(); 114 | flock($this->dataFileHandle, LOCK_UN); 115 | return $this->dataCache[$key]; 116 | } 117 | 118 | /** 119 | * 清零销毁存储数据 120 | */ 121 | public function destroy() 122 | { 123 | @unlink($this->dataFile); 124 | } 125 | 126 | /** 127 | * 写入磁盘 128 | * @return number 129 | */ 130 | protected function writeToDisk() 131 | { 132 | return file_put_contents($this->dataFile, "dataCache, true). ';'); 133 | } 134 | 135 | /** 136 | * 从磁盘读 137 | */ 138 | protected function readDataFromDisk() 139 | { 140 | $cache = include $this->dataFile; 141 | if(is_array($cache)) 142 | { 143 | $this->dataCache = $cache; 144 | } 145 | $this->lastCacheTime = time(); 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /PHPMailer/.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | php: 3 | - 5.6 4 | - 5.5 5 | - 5.4 6 | - 5.3 7 | - hhvm 8 | 9 | matrix: 10 | allow_failures: 11 | - php: hhvm 12 | 13 | before_install: 14 | - sudo apt-get update -qq 15 | - sudo apt-get install -y -qq postfix 16 | before_script: 17 | - sudo service postfix stop 18 | - smtp-sink -d "%d.%H.%M.%S" localhost:2500 1000 & 19 | - mkdir -p build/logs 20 | - cd test 21 | - cp testbootstrap-dist.php testbootstrap.php 22 | - chmod +x fakesendmail.sh 23 | - sudo mkdir -p /var/qmail/bin 24 | - sudo cp fakesendmail.sh /var/qmail/bin/sendmail 25 | - sudo cp fakesendmail.sh /usr/sbin/sendmail 26 | - echo 'sendmail_path = "/usr/sbin/sendmail -t -i "' | sudo tee "/home/travis/.phpenv/versions/`php -r 'echo PHP_VERSION;'`/etc/conf.d/sendmail.ini" 27 | - pwd 28 | - ls -al 29 | script: 30 | - phpunit --configuration ../travis.phpunit.xml.dist 31 | after_script: 32 | - wget https://scrutinizer-ci.com/ocular.phar 33 | - php ocular.phar code-coverage:upload --format=php-clover ../build/logs/clover.xml 34 | -------------------------------------------------------------------------------- /PHPMailer/PHPMailerAutoload.php: -------------------------------------------------------------------------------- 1 | 8 | * @author Jim Jagielski (jimjag) 9 | * @author Andy Prevost (codeworxtech) 10 | * @author Brent R. Matzelle (original founder) 11 | * @copyright 2012 - 2014 Marcus Bointon 12 | * @copyright 2010 - 2012 Jim Jagielski 13 | * @copyright 2004 - 2009 Andy Prevost 14 | * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License 15 | * @note This program is distributed in the hope that it will be useful - WITHOUT 16 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 17 | * FITNESS FOR A PARTICULAR PURPOSE. 18 | */ 19 | 20 | /** 21 | * PHPMailer SPL autoloader. 22 | * @param string $classname The name of the class to load 23 | */ 24 | function PHPMailerAutoload($classname) 25 | { 26 | //Can't use __DIR__ as it's only in PHP 5.3+ 27 | $filename = dirname(__FILE__).DIRECTORY_SEPARATOR.'class.'.strtolower($classname).'.php'; 28 | if (is_readable($filename)) { 29 | require $filename; 30 | } 31 | } 32 | 33 | if (version_compare(PHP_VERSION, '5.1.2', '>=')) { 34 | //SPL autoloading was introduced in PHP 5.1.2 35 | if (version_compare(PHP_VERSION, '5.3.0', '>=')) { 36 | spl_autoload_register('PHPMailerAutoload', true, true); 37 | } else { 38 | spl_autoload_register('PHPMailerAutoload'); 39 | } 40 | } else { 41 | /** 42 | * Fall back to traditional autoload for old PHP versions 43 | * @param string $classname The name of the class to load 44 | */ 45 | function __autoload($classname) 46 | { 47 | PHPMailerAutoload($classname); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /PHPMailer/VERSION: -------------------------------------------------------------------------------- 1 | 5.2.9 -------------------------------------------------------------------------------- /PHPMailer/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "phpmailer/phpmailer", 3 | "type": "library", 4 | "description": "PHPMailer is a full-featured email creation and transfer class for PHP", 5 | "authors": [ 6 | { 7 | "name": "Marcus Bointon", 8 | "email": "phpmailer@synchromedia.co.uk" 9 | }, 10 | { 11 | "name": "Jim Jagielski", 12 | "email": "jimjag@gmail.com" 13 | }, 14 | { 15 | "name": "Andy Prevost", 16 | "email": "codeworxtech@users.sourceforge.net" 17 | }, 18 | { 19 | "name": "Brent R. Matzelle" 20 | } 21 | ], 22 | "require": { 23 | "php": ">=5.0.0" 24 | }, 25 | "require-dev": { 26 | "phpdocumentor/phpdocumentor": "*", 27 | "phpunit/phpunit": "4.1.*" 28 | }, 29 | "autoload": { 30 | "classmap": ["class.phpmailer.php", "class.pop3.php", "class.smtp.php"] 31 | }, 32 | "license": "LGPL-2.1" 33 | } -------------------------------------------------------------------------------- /PHPMailer/docs/Callback_function_notes.txt: -------------------------------------------------------------------------------- 1 | NEW CALLBACK FUNCTION: 2 | ====================== 3 | 4 | We have had requests for a method to process the results of sending emails 5 | through PHPMailer. In this new release, we have implemented a callback 6 | function that passes the results of each email sent (to, cc, and/or bcc). 7 | We have provided an example that echos the results back to the screen. The 8 | callback function can be used for any purpose. With minor modifications, the 9 | callback function can be used to create CSV logs, post results to databases, 10 | etc. 11 | 12 | Please review the test.php script for the example. 13 | 14 | It's pretty straight forward. 15 | 16 | Enjoy! 17 | Andy 18 | -------------------------------------------------------------------------------- /PHPMailer/docs/DomainKeys_notes.txt: -------------------------------------------------------------------------------- 1 | CREATE DKIM KEYS and DNS Resource Record: 2 | ========================================= 3 | 4 | To create DomainKeys Identified Mail keys, visit: 5 | http://dkim.worxware.com/ 6 | ... read the information, fill in the form, and download the ZIP file 7 | containing the public key, private key, DNS Resource Record and instructions 8 | to add to your DNS Zone Record, and the PHPMailer code to enable DKIM 9 | digital signing. 10 | 11 | /*** PROTECT YOUR PRIVATE & PUBLIC KEYS ***/ 12 | 13 | You need to protect your DKIM private and public keys from being viewed or 14 | accessed. Add protection to your .htaccess file as in this example: 15 | 16 | # secure htkeyprivate file 17 | 18 | order allow,deny 19 | deny from all 20 | 21 | 22 | # secure htkeypublic file 23 | 24 | order allow,deny 25 | deny from all 26 | 27 | 28 | (the actual .htaccess additions are in the ZIP file sent back to you from 29 | http://dkim.worxware.com/ 30 | 31 | A few notes on using DomainKey Identified Mail (DKIM): 32 | 33 | You do not need to use PHPMailer to DKIM sign emails IF: 34 | - you enable DomainKey support and add the DNS resource record 35 | - you use your outbound mail server 36 | 37 | If you are a third-party emailer that works on behalf of domain owners to 38 | send their emails from your own server: 39 | - you absolutely have to DKIM sign outbound emails 40 | - the domain owner has to add the DNS resource record to match the 41 | private key, public key, selector, identity, and domain that you create 42 | - use caution with the "selector" ... at least one "selector" will already 43 | exist in the DNS Zone Record of the domain at the domain owner's server 44 | you need to ensure that the "selector" you use is unique 45 | Note: since the IP address will not match the domain owner's DNS Zone record 46 | you can be certain that email providers that validate based on DomainKey will 47 | check the domain owner's DNS Zone record for your DNS resource record. Before 48 | sending out emails on behalf of domain owners, ensure they have entered the 49 | DNS resource record you provided them. 50 | 51 | Enjoy! 52 | Andy 53 | 54 | PS. if you need additional information about DKIM, please see: 55 | http://www.dkim.org/info/dkim-faq.html 56 | -------------------------------------------------------------------------------- /PHPMailer/docs/Note_for_SMTP_debugging.txt: -------------------------------------------------------------------------------- 1 | If you are having problems connecting or sending emails through your SMTP server, the SMTP class can provide more information about the processing/errors taking place. 2 | Use the debug functionality of the class to see what's going on in your connections. To do that, set the debug level in your script. For example: 3 | 4 | $mail->SMTPDebug = 1; 5 | $mail->isSMTP(); // telling the class to use SMTP 6 | $mail->SMTPAuth = true; // enable SMTP authentication 7 | $mail->Port = 26; // set the SMTP port 8 | $mail->Host = "mail.yourhost.com"; // SMTP server 9 | $mail->Username = "name@yourhost.com"; // SMTP account username 10 | $mail->Password = "your password"; // SMTP account password 11 | 12 | Notes on this: 13 | $mail->SMTPDebug = 0; ... will disable debugging (you can also leave this out completely, 0 is the default) 14 | $mail->SMTPDebug = 1; ... will echo errors and server responses 15 | $mail->SMTPDebug = 2; ... will echo errors, server responses and client messages 16 | 17 | And finally, don't forget to disable debugging before going into production. 18 | -------------------------------------------------------------------------------- /PHPMailer/docs/extending.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Examples using phpmailer 4 | 5 | 6 | 7 | 8 |

Examples using PHPMailer

9 | 10 |

1. Advanced Example

11 |

12 | 13 | This demonstrates sending multiple email messages with binary attachments 14 | from a MySQL database using multipart/alternative messages.

15 | 16 |

 17 | require 'PHPMailerAutoload.php';
 18 | 
 19 | $mail = new PHPMailer();
 20 | 
 21 | $mail->From     = 'list@example.com';
 22 | $mail->FromName = 'List manager';
 23 | $mail->Host     = 'smtp1.example.com;smtp2.example.com';
 24 | $mail->Mailer   = 'smtp';
 25 | 
 26 | @mysqli_connect('localhost','root','password');
 27 | @mysqli_select_db("my_company");
 28 | $query = "SELECT full_name, email, photo FROM employee";
 29 | $result = @mysqli_query($query);
 30 | 
 31 | while ($row = mysqli_fetch_assoc($result))
 32 | {
 33 |     // HTML body
 34 |     $body  = "Hello <font size=\"4\">" . $row['full_name'] . "</font>, <p>";
 35 |     $body .= "<i>Your</i> personal photograph to this message.<p>";
 36 |     $body .= "Sincerely, <br>";
 37 |     $body .= "phpmailer List manager";
 38 | 
 39 |     // Plain text body (for mail clients that cannot read HTML)
 40 |     $text_body  = 'Hello ' . $row['full_name'] . ", \n\n";
 41 |     $text_body .= "Your personal photograph to this message.\n\n";
 42 |     $text_body .= "Sincerely, \n";
 43 |     $text_body .= 'phpmailer List manager';
 44 | 
 45 |     $mail->Body    = $body;
 46 |     $mail->AltBody = $text_body;
 47 |     $mail->addAddress($row['email'], $row['full_name']);
 48 |     $mail->addStringAttachment($row['photo'], 'YourPhoto.jpg');
 49 | 
 50 |     if(!$mail->send())
 51 |         echo "There has been a mail error sending to " . $row['email'] . "<br>";
 52 | 
 53 |     // Clear all addresses and attachments for next loop
 54 |     $mail->clearAddresses();
 55 |     $mail->clearAttachments();
 56 | }
 57 | 
58 |

59 | 60 |

2. Extending PHPMailer

61 |

62 | 63 | Extending classes with inheritance is one of the most 64 | powerful features of object-oriented programming. It allows you to make changes to the 65 | original class for your own personal use without hacking the original 66 | classes, and it's very easy to do: 67 | 68 |

69 | Here's a class that extends the phpmailer class and sets the defaults 70 | for the particular site:
71 | PHP include file: my_phpmailer.php 72 |

73 | 74 |

 75 | require 'PHPMailerAutoload.php';
 76 | 
 77 | class my_phpmailer extends PHPMailer {
 78 |     // Set default variables for all new objects
 79 |     public $From     = 'from@example.com';
 80 |     public $FromName = 'Mailer';
 81 |     public $Host     = 'smtp1.example.com;smtp2.example.com';
 82 |     public $Mailer   = 'smtp';                         // Alternative to isSMTP()
 83 |     public $WordWrap = 75;
 84 | 
 85 |     // Replace the default debug output function
 86 |     protected function edebug($msg) {
 87 |         print('My Site Error');
 88 |         print('Description:');
 89 |         printf('%s', $msg);
 90 |         exit;
 91 |     }
 92 | 
 93 |     //Extend the send function
 94 |     public function send() {
 95 |         $this->Subject = '[Yay for me!] '.$this->Subject;
 96 |         return parent::send()
 97 |     }
 98 | 
 99 |     // Create an additional function
100 |     public function do_something($something) {
101 |         // Place your new code here
102 |     }
103 | }
104 | 
105 |
106 | Now here's a normal PHP page in the site, which will have all the defaults set above:
107 | 108 |
109 | require 'my_phpmailer.php';
110 | 
111 | // Instantiate your new class
112 | $mail = new my_phpmailer;
113 | 
114 | // Now you only need to add the necessary stuff
115 | $mail->addAddress('josh@example.com', 'Josh Adams');
116 | $mail->Subject = 'Here is the subject';
117 | $mail->Body    = 'This is the message body';
118 | $mail->addAttachment('c:/temp/11-10-00.zip', 'new_name.zip');  // optional name
119 | 
120 | if(!$mail->send())
121 | {
122 |    echo 'There was an error sending the message';
123 |    exit;
124 | }
125 | 
126 | echo 'Message was sent successfully';
127 | 
128 | 129 | 130 | -------------------------------------------------------------------------------- /PHPMailer/docs/faq.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | PHPMailer FAQ 4 | 5 | 6 |

PHPMailer FAQ

7 |
    8 |
  • Q: I am concerned that using include files will take up too much 9 | processing time on my computer. How can I make it run faster?
    10 | A: PHP by itself is fairly fast, but it recompiles scripts every time they are run, which takes up valuable 11 | computer resources. You can bypass this by using an opcode cache which compiles 12 | PHP code and store it in memory to reduce overhead immensely. APC 13 | (Alternative PHP Cache) is a free opcode cache extension in the PECL library.
  • 14 |
  • Q: Which mailer gives me the best performance?
    15 | A: On a single machine the sendmail (or Qmail) is fastest overall. 16 | Next fastest is mail() to give you the best performance. Both do not have the overhead of SMTP. 17 | If you do not have a local mail server (as is typical on Windows), SMTP is your only option.
  • 18 |
  • Q: When I try to attach a file with on my server I get a 19 | "Could not find {file} on filesystem error". Why is this?
    20 | A: If you are using a Unix machine this is probably because the user 21 | running your web server does not have read access to the directory in question. If you are using Windows, 22 | then the problem is probably that you have used single backslashes to denote directories (\). 23 | A single backslash has a special meaning to PHP so these are not 24 | valid. Instead use double backslashes ("\\") or a single forward 25 | slash ("/").
  • 26 |
27 | 28 | 29 | -------------------------------------------------------------------------------- /PHPMailer/docs/generatedocs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Regenerate PHPMailer documentation 3 | # Run from within the docs folder 4 | rm -rf phpdoc/* 5 | phpdoc --directory .. --target ./phpdoc --ignore test/,examples/,extras/,test_script/,vendor/,language/ --sourcecode --force --title PHPMailer --template="clean" 6 | # You can merge regenerated docs into a separate docs working copy without messing up the git status like so: 7 | # rsync -a --delete --exclude ".git" --exclude "phpdoc-cache-*/" --exclude "README.md" phpdoc/ ../../phpmailer-docs 8 | # After updating docs, push/PR them to the phpmailer gh-pages branch: https://github.com/PHPMailer/PHPMailer/tree/gh-pages 9 | -------------------------------------------------------------------------------- /PHPMailer/docs/pop3_article.txt: -------------------------------------------------------------------------------- 1 | This is built for PHP Mailer 1.72 and was not tested with any previous version. It was developed under PHP 4.3.11 (E_ALL). It works under PHP 5 and 5.1 with E_ALL, but not in Strict mode due to var deprecation (but then neither does PHP Mailer either!). It follows the RFC 1939 standard explicitly and is fully commented. 2 | 3 | With that noted, here is how to implement it: 4 | 5 | I didn't want to modify the PHP Mailer classes at all, so you will have to include/require this class along with the base one. It can sit quite happily in the phpmailer directory. 6 | 7 | When you need it, create your POP3 object 8 | 9 | Right before I invoke PHP Mailer I activate the POP3 authorisation. POP3 before SMTP is a process whereby you login to your web hosts POP3 mail server BEFORE sending out any emails via SMTP. The POP3 logon 'verifies' your ability to send email by SMTP, which typically otherwise blocks you. On my web host (Pair Networks) a single POP3 logon is enough to 'verify' you for 90 minutes. Here is some sample PHP code that activates the POP3 logon and then sends an email via PHP Mailer: 10 | 11 | authorise('pop3.example.com', 110, 30, 'mailer', 'password', 1); 13 | $mail = new PHPMailer(); $mail->SMTPDebug = 2; $mail->isSMTP(); 14 | $mail->isHTML(false); $mail->Host = 'relay.example.com'; 15 | $mail->From = 'mailer@example.com'; 16 | $mail->FromName = 'Example Mailer'; 17 | $mail->Subject = 'My subject'; 18 | $mail->Body = 'Hello world'; 19 | $mail->addAddress('rich@corephp.co.uk', 'Richard Davey'); 20 | if (!$mail->send()) { 21 | echo $mail->ErrorInfo; 22 | } 23 | ?> 24 | 25 | The PHP Mailer parts of this code should be obvious to anyone who has used PHP Mailer before. One thing to note - you almost certainly will not need to use SMTP Authentication *and* POP3 before SMTP together. The Authorisation method is a proxy method to all of the others within that class. There are connect, Logon and disconnect methods available, but I wrapped them in the single Authorisation one to make things easier. 26 | The Parameters 27 | 28 | The authorise parameters are as follows: 29 | 30 | $pop->authorise('pop3.example.com', 110, 30, 'mailer', 'password', 1); 31 | 32 | 1. pop3.example.com - The POP3 Mail Server Name (hostname or IP address) 33 | 2. 110 - The POP3 Port on which to connect (default is usually 110, but check with your host) 34 | 3. 30 - A connection time-out value (in seconds) 35 | 4. mailer - The POP3 Username required to logon 36 | 5. password - The POP3 Password required to logon 37 | 6. 1 - The class debug level (0 = off, 1+ = debug output is echoed to the browser) 38 | 39 | Final Comments + the Download 40 | 41 | 1) This class does not support APOP connections. This is only because I did not have an APOP server to test with, but if you'd like to see that added just contact me. 42 | 43 | 2) Opening and closing lots of POP3 connections can be quite a resource/network drain. If you need to send a whole batch of emails then just perform the authentication once at the start, and then loop through your mail sending script. Providing this process doesn't take longer than the verification period lasts on your POP3 server, you should be fine. With my host that period is 90 minutes, i.e. plenty of time. 44 | 45 | 3) If you have heavy requirements for this script (i.e. send a LOT of email on a frequent basis) then I would advise seeking out an alternative sending method (direct SMTP ideally). If this isn't possible then you could modify this class so the 'last authorised' date is recorded somewhere (MySQL, Flat file, etc) meaning you only open a new connection if the old one has expired, saving you precious overhead. 46 | 47 | 4) There are lots of other POP3 classes for PHP available. However most of them implement the full POP3 command set, where-as this one is purely for authentication, and much lighter as a result. However using any of the other POP3 classes to just logon to your server would have the same net result. At the end of the day, use whatever method you feel most comfortable with. 48 | Download 49 | 50 | My thanks to Chris Ryan for the inspiration (even if indirectly, via his SMTP class) 51 | -------------------------------------------------------------------------------- /PHPMailer/examples/contents.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PHPMailer Test 6 | 7 | 8 |
9 |

This is a test of PHPMailer.

10 |
11 | PHPMailer rocks 12 |
13 |

This example uses HTML.

14 |

The PHPMailer image at the top has been embedded automatically.

15 |
16 | 17 | 18 | -------------------------------------------------------------------------------- /PHPMailer/examples/exceptions.phps: -------------------------------------------------------------------------------- 1 | setFrom('from@example.com', 'First Last'); 14 | //Set an alternative reply-to address 15 | $mail->addReplyTo('replyto@example.com', 'First Last'); 16 | //Set who the message is to be sent to 17 | $mail->addAddress('whoto@example.com', 'John Doe'); 18 | //Set the subject line 19 | $mail->Subject = 'PHPMailer Exceptions test'; 20 | //Read an HTML message body from an external file, convert referenced images to embedded, 21 | //and convert the HTML into a basic plain-text alternative body 22 | $mail->msgHTML(file_get_contents('contents.html'), dirname(__FILE__)); 23 | //Replace the plain text body with one created manually 24 | $mail->AltBody = 'This is a plain-text message body'; 25 | //Attach an image file 26 | $mail->addAttachment('images/phpmailer_mini.png'); 27 | //send the message 28 | //Note that we don't need check the response from this because it will throw an exception if it has trouble 29 | $mail->send(); 30 | echo "Message sent!"; 31 | } catch (phpmailerException $e) { 32 | echo $e->errorMessage(); //Pretty error messages from PHPMailer 33 | } catch (Exception $e) { 34 | echo $e->getMessage(); //Boring error messages from anything else! 35 | } 36 | -------------------------------------------------------------------------------- /PHPMailer/examples/gmail.phps: -------------------------------------------------------------------------------- 1 | isSMTP(); 17 | 18 | //Enable SMTP debugging 19 | // 0 = off (for production use) 20 | // 1 = client messages 21 | // 2 = client and server messages 22 | $mail->SMTPDebug = 2; 23 | 24 | //Ask for HTML-friendly debug output 25 | $mail->Debugoutput = 'html'; 26 | 27 | //Set the hostname of the mail server 28 | $mail->Host = 'smtp.gmail.com'; 29 | 30 | //Set the SMTP port number - 587 for authenticated TLS, a.k.a. RFC4409 SMTP submission 31 | $mail->Port = 587; 32 | 33 | //Set the encryption system to use - ssl (deprecated) or tls 34 | $mail->SMTPSecure = 'tls'; 35 | 36 | //Whether to use SMTP authentication 37 | $mail->SMTPAuth = true; 38 | 39 | //Username to use for SMTP authentication - use full email address for gmail 40 | $mail->Username = "username@gmail.com"; 41 | 42 | //Password to use for SMTP authentication 43 | $mail->Password = "yourpassword"; 44 | 45 | //Set who the message is to be sent from 46 | $mail->setFrom('from@example.com', 'First Last'); 47 | 48 | //Set an alternative reply-to address 49 | $mail->addReplyTo('replyto@example.com', 'First Last'); 50 | 51 | //Set who the message is to be sent to 52 | $mail->addAddress('whoto@example.com', 'John Doe'); 53 | 54 | //Set the subject line 55 | $mail->Subject = 'PHPMailer GMail SMTP test'; 56 | 57 | //Read an HTML message body from an external file, convert referenced images to embedded, 58 | //convert HTML into a basic plain-text alternative body 59 | $mail->msgHTML(file_get_contents('contents.html'), dirname(__FILE__)); 60 | 61 | //Replace the plain text body with one created manually 62 | $mail->AltBody = 'This is a plain-text message body'; 63 | 64 | //Attach an image file 65 | $mail->addAttachment('images/phpmailer_mini.png'); 66 | 67 | //send the message, check for errors 68 | if (!$mail->send()) { 69 | echo "Mailer Error: " . $mail->ErrorInfo; 70 | } else { 71 | echo "Message sent!"; 72 | } 73 | -------------------------------------------------------------------------------- /PHPMailer/examples/images/phpmailer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudXNS/mss/3c7af06ef22f49b78f7f18a3ac69ef785ad7591f/PHPMailer/examples/images/phpmailer.png -------------------------------------------------------------------------------- /PHPMailer/examples/images/phpmailer_mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CloudXNS/mss/3c7af06ef22f49b78f7f18a3ac69ef785ad7591f/PHPMailer/examples/images/phpmailer_mini.png -------------------------------------------------------------------------------- /PHPMailer/examples/mail.phps: -------------------------------------------------------------------------------- 1 | setFrom('from@example.com', 'First Last'); 12 | //Set an alternative reply-to address 13 | $mail->addReplyTo('replyto@example.com', 'First Last'); 14 | //Set who the message is to be sent to 15 | $mail->addAddress('whoto@example.com', 'John Doe'); 16 | //Set the subject line 17 | $mail->Subject = 'PHPMailer mail() test'; 18 | //Read an HTML message body from an external file, convert referenced images to embedded, 19 | //convert HTML into a basic plain-text alternative body 20 | $mail->msgHTML(file_get_contents('contents.html'), dirname(__FILE__)); 21 | //Replace the plain text body with one created manually 22 | $mail->AltBody = 'This is a plain-text message body'; 23 | //Attach an image file 24 | $mail->addAttachment('images/phpmailer_mini.png'); 25 | 26 | //send the message, check for errors 27 | if (!$mail->send()) { 28 | echo "Mailer Error: " . $mail->ErrorInfo; 29 | } else { 30 | echo "Message sent!"; 31 | } 32 | -------------------------------------------------------------------------------- /PHPMailer/examples/mailing_list.phps: -------------------------------------------------------------------------------- 1 | isSMTP(); 14 | $mail->Host = 'smtp.example.com'; 15 | $mail->SMTPAuth = true; 16 | $mail->SMTPKeepAlive = true; // SMTP connection will not close after each email sent, reduces SMTP overhead 17 | $mail->Port = 25; 18 | $mail->Username = 'yourname@example.com'; 19 | $mail->Password = 'yourpassword'; 20 | $mail->setFrom('list@example.com', 'List manager'); 21 | $mail->addReplyTo('list@example.com', 'List manager'); 22 | 23 | $mail->Subject = "PHPMailer Simple database mailing list test"; 24 | 25 | //Same body for all messages, so set this before the sending loop 26 | //If you generate a different body for each recipient (e.g. you're using a templating system), 27 | //set it inside the loop 28 | $mail->msgHTML($body); 29 | //msgHTML also sets AltBody, but if you want a custom one, set it afterwards 30 | $mail->AltBody = 'To view the message, please use an HTML compatible email viewer!'; 31 | 32 | //Connect to the database and select the recipients from your mailing list that have not yet been sent to 33 | //You'll need to alter this to match your database 34 | $mysql = mysqli_connect('localhost', 'username', 'password'); 35 | mysqli_select_db($mysql, 'mydb'); 36 | $result = mysqli_query($mysql, 'SELECT full_name, email, photo FROM mailinglist WHERE sent = false'); 37 | 38 | foreach ($result as $row) { //This iterator syntax only works in PHP 5.4+ 39 | $mail->addAddress($row['email'], $row['full_name']); 40 | if (!empty($row['photo'])) { 41 | $mail->addStringAttachment($row['photo'], 'YourPhoto.jpg'); //Assumes the image data is stored in the DB 42 | } 43 | 44 | if (!$mail->send()) { 45 | echo "Mailer Error (" . str_replace("@", "@", $row["email"]) . ') ' . $mail->ErrorInfo . '
'; 46 | break; //Abandon sending 47 | } else { 48 | echo "Message sent to :" . $row['full_name'] . ' (' . str_replace("@", "@", $row['email']) . ')
'; 49 | //Mark it as sent in the DB 50 | mysqli_query( 51 | $mysql, 52 | "UPDATE mailinglist SET sent = true WHERE email = '" . 53 | mysqli_real_escape_string($mysql, $row['email']) . "'" 54 | ); 55 | } 56 | // Clear all addresses and attachments for next loop 57 | $mail->clearAddresses(); 58 | $mail->clearAttachments(); 59 | } 60 | -------------------------------------------------------------------------------- /PHPMailer/examples/pop_before_smtp.phps: -------------------------------------------------------------------------------- 1 | isSMTP(); 18 | //Enable SMTP debugging 19 | // 0 = off (for production use) 20 | // 1 = client messages 21 | // 2 = client and server messages 22 | $mail->SMTPDebug = 2; 23 | //Ask for HTML-friendly debug output 24 | $mail->Debugoutput = 'html'; 25 | //Set the hostname of the mail server 26 | $mail->Host = "mail.example.com"; 27 | //Set the SMTP port number - likely to be 25, 465 or 587 28 | $mail->Port = 25; 29 | //Whether to use SMTP authentication 30 | $mail->SMTPAuth = false; 31 | //Set who the message is to be sent from 32 | $mail->setFrom('from@example.com', 'First Last'); 33 | //Set an alternative reply-to address 34 | $mail->addReplyTo('replyto@example.com', 'First Last'); 35 | //Set who the message is to be sent to 36 | $mail->addAddress('whoto@example.com', 'John Doe'); 37 | //Set the subject line 38 | $mail->Subject = 'PHPMailer POP-before-SMTP test'; 39 | //Read an HTML message body from an external file, convert referenced images to embedded, 40 | //and convert the HTML into a basic plain-text alternative body 41 | $mail->msgHTML(file_get_contents('contents.html'), dirname(__FILE__)); 42 | //Replace the plain text body with one created manually 43 | $mail->AltBody = 'This is a plain-text message body'; 44 | //Attach an image file 45 | $mail->addAttachment('images/phpmailer_mini.png'); 46 | //send the message 47 | //Note that we don't need check the response from this because it will throw an exception if it has trouble 48 | $mail->send(); 49 | echo "Message sent!"; 50 | } catch (phpmailerException $e) { 51 | echo $e->errorMessage(); //Pretty error messages from PHPMailer 52 | } catch (Exception $e) { 53 | echo $e->getMessage(); //Boring error messages from anything else! 54 | } 55 | -------------------------------------------------------------------------------- /PHPMailer/examples/scripts/shAutoloader.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | var sh = SyntaxHighlighter; 4 | 5 | /** 6 | * Provides functionality to dynamically load only the brushes that a needed to render the current page. 7 | * 8 | * There are two syntaxes that autoload understands. For example: 9 | * 10 | * SyntaxHighlighter.autoloader( 11 | * [ 'applescript', 'Scripts/shBrushAppleScript.js' ], 12 | * [ 'actionscript3', 'as3', 'Scripts/shBrushAS3.js' ] 13 | * ); 14 | * 15 | * or a more easily comprehendable one: 16 | * 17 | * SyntaxHighlighter.autoloader( 18 | * 'applescript Scripts/shBrushAppleScript.js', 19 | * 'actionscript3 as3 Scripts/shBrushAS3.js' 20 | * ); 21 | */ 22 | sh.autoloader = function() 23 | { 24 | var list = arguments, 25 | elements = sh.findElements(), 26 | brushes = {}, 27 | scripts = {}, 28 | all = SyntaxHighlighter.all, 29 | allCalled = false, 30 | allParams = null, 31 | i 32 | ; 33 | 34 | SyntaxHighlighter.all = function(params) 35 | { 36 | allParams = params; 37 | allCalled = true; 38 | }; 39 | 40 | function addBrush(aliases, url) 41 | { 42 | for (var i = 0; i < aliases.length; i++) 43 | brushes[aliases[i]] = url; 44 | }; 45 | 46 | function getAliases(item) 47 | { 48 | return item.pop 49 | ? item 50 | : item.split(/\s+/) 51 | ; 52 | } 53 | 54 | // create table of aliases and script urls 55 | for (i = 0; i < list.length; i++) 56 | { 57 | var aliases = getAliases(list[i]), 58 | url = aliases.pop() 59 | ; 60 | 61 | addBrush(aliases, url); 62 | } 63 | 64 | // dynamically add