Initial checkin v13.0
This commit is contained in:
556
src/api/AdapterBase.js
Normal file
556
src/api/AdapterBase.js
Normal file
@@ -0,0 +1,556 @@
|
||||
/*
|
||||
This file is part of Ice Framework.
|
||||
|
||||
Ice Framework is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Ice Framework is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Ice Framework. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
------------------------------------------------------------------
|
||||
|
||||
Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd]
|
||||
Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah)
|
||||
*/
|
||||
|
||||
|
||||
function AdapterBase(endPoint) {
|
||||
|
||||
}
|
||||
|
||||
this.moduleRelativeURL = null;
|
||||
this.tableData = new Array();
|
||||
this.sourceData = new Array();
|
||||
this.filter = null;
|
||||
this.origFilter = null;
|
||||
this.orderBy = null;
|
||||
this.currentElement = null;
|
||||
|
||||
AdapterBase.inherits(IceHRMBase);
|
||||
|
||||
AdapterBase.method('initAdapter' , function(endPoint,tab,filter,orderBy) {
|
||||
this.moduleRelativeURL = baseUrl;
|
||||
this.table = endPoint;
|
||||
if(tab == undefined || tab == null){
|
||||
this.tab = endPoint;
|
||||
}else{
|
||||
this.tab = tab;
|
||||
}
|
||||
|
||||
if(filter == undefined || filter == null){
|
||||
this.filter = null;
|
||||
}else{
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
this.origFilter = this.filter;
|
||||
|
||||
if(orderBy == undefined || orderBy == null){
|
||||
this.orderBy = null;
|
||||
}else{
|
||||
this.orderBy = orderBy;
|
||||
}
|
||||
|
||||
this.trackEvent("initAdapter",tab);
|
||||
|
||||
this.requestCache = new RequestCache();
|
||||
|
||||
});
|
||||
|
||||
AdapterBase.method('setFilter', function(filter) {
|
||||
this.filter = filter;
|
||||
});
|
||||
|
||||
AdapterBase.method('getFilter', function() {
|
||||
return this.filter;
|
||||
});
|
||||
|
||||
AdapterBase.method('setOrderBy', function(orderBy) {
|
||||
this.orderBy = orderBy;
|
||||
});
|
||||
|
||||
AdapterBase.method('getOrderBy', function() {
|
||||
return this.orderBy;
|
||||
});
|
||||
|
||||
/**
|
||||
* @method add
|
||||
* @param object {Array} object data to be added to database
|
||||
* @param getFunctionCallBackData {Array} once a success is returned call get() function for this module with these parameters
|
||||
* @param callGetFunction {Boolean} if false the get function of the module will not be called (default: true)
|
||||
* @param successCallback {Function} this will get called after success response
|
||||
*/
|
||||
|
||||
AdapterBase.method('add', function(object,getFunctionCallBackData,callGetFunction,successCallback) {
|
||||
var that = this;
|
||||
if(callGetFunction == undefined || callGetFunction == null){
|
||||
callGetFunction = true;
|
||||
}
|
||||
$(object).attr('a','add');
|
||||
$(object).attr('t',this.table);
|
||||
$.post(this.moduleRelativeURL, object, function(data) {
|
||||
if(data.status == "SUCCESS"){
|
||||
that.addSuccessCallBack(getFunctionCallBackData,data.object, callGetFunction, successCallback, that);
|
||||
}else{
|
||||
that.addFailCallBack(getFunctionCallBackData,data.object);
|
||||
}
|
||||
},"json");
|
||||
this.trackEvent("add",this.tab,this.table);
|
||||
});
|
||||
|
||||
AdapterBase.method('addSuccessCallBack', function(callBackData,serverData, callGetFunction, successCallback, thisObject) {
|
||||
if(callGetFunction){
|
||||
this.get(callBackData);
|
||||
}
|
||||
this.initFieldMasterData();
|
||||
if(successCallback != undefined && successCallback != null){
|
||||
successCallback.apply(thisObject,[serverData]);
|
||||
}
|
||||
this.trackEvent("addSuccess",this.tab,this.table);
|
||||
});
|
||||
|
||||
AdapterBase.method('addFailCallBack', function(callBackData,serverData) {
|
||||
this.showMessage("Error saving",serverData);
|
||||
this.trackEvent("addFailed",this.tab,this.table);
|
||||
});
|
||||
|
||||
AdapterBase.method('deleteObj', function(id,callBackData) {
|
||||
var that = this;
|
||||
$.post(this.moduleRelativeURL, {'t':this.table,'a':'delete','id':id}, function(data) {
|
||||
if(data.status == "SUCCESS"){
|
||||
that.deleteSuccessCallBack(callBackData,data.object);
|
||||
}else{
|
||||
that.deleteFailCallBack(callBackData,data.object);
|
||||
}
|
||||
},"json");
|
||||
this.trackEvent("delete",this.tab,this.table);
|
||||
});
|
||||
|
||||
AdapterBase.method('deleteSuccessCallBack', function(callBackData,serverData) {
|
||||
this.get(callBackData);
|
||||
this.clearDeleteParams();
|
||||
});
|
||||
|
||||
AdapterBase.method('deleteFailCallBack', function(callBackData,serverData) {
|
||||
this.clearDeleteParams();
|
||||
this.showMessage("Error Occurred while Deleting Item",serverData);
|
||||
});
|
||||
|
||||
AdapterBase.method('get', function(callBackData) {
|
||||
var that = this;
|
||||
|
||||
if(this.getRemoteTable()){
|
||||
this.createTableServer(this.getTableName());
|
||||
$("#"+this.getTableName()+'Form').hide();
|
||||
$("#"+this.getTableName()).show();
|
||||
return;
|
||||
}
|
||||
|
||||
var sourceMappingJson = JSON.stringify(this.getSourceMapping());
|
||||
|
||||
var filterJson = "";
|
||||
if(this.getFilter() != null){
|
||||
filterJson = JSON.stringify(this.getFilter());
|
||||
}
|
||||
|
||||
var orderBy = "";
|
||||
if(this.getOrderBy() != null){
|
||||
orderBy = this.getOrderBy();
|
||||
}
|
||||
|
||||
sourceMappingJson = this.fixJSON(sourceMappingJson);
|
||||
filterJson = this.fixJSON(filterJson);
|
||||
|
||||
$.post(this.moduleRelativeURL, {'t':this.table,'a':'get','sm':sourceMappingJson,'ft':filterJson,'ob':orderBy}, function(data) {
|
||||
if(data.status == "SUCCESS"){
|
||||
that.getSuccessCallBack(callBackData,data.object);
|
||||
}else{
|
||||
that.getFailCallBack(callBackData,data.object);
|
||||
}
|
||||
},"json");
|
||||
|
||||
that.initFieldMasterData();
|
||||
|
||||
this.trackEvent("get",this.tab,this.table);
|
||||
//var url = this.getDataUrl();
|
||||
//console.log(url);
|
||||
});
|
||||
|
||||
|
||||
AdapterBase.method('getDataUrl', function(columns) {
|
||||
var that = this;
|
||||
var sourceMappingJson = JSON.stringify(this.getSourceMapping());
|
||||
|
||||
var columns = JSON.stringify(columns);
|
||||
|
||||
var filterJson = "";
|
||||
if(this.getFilter() != null){
|
||||
filterJson = JSON.stringify(this.getFilter());
|
||||
}
|
||||
|
||||
var orderBy = "";
|
||||
if(this.getOrderBy() != null){
|
||||
orderBy = this.getOrderBy();
|
||||
}
|
||||
|
||||
var url = this.moduleRelativeURL.replace("service.php","data.php");
|
||||
url = url+"?"+"t="+this.table;
|
||||
url = url+"&"+"sm="+this.fixJSON(sourceMappingJson);
|
||||
url = url+"&"+"cl="+this.fixJSON(columns);
|
||||
url = url+"&"+"ft="+this.fixJSON(filterJson);
|
||||
url = url+"&"+"ob="+orderBy;
|
||||
|
||||
if(this.isSubProfileTable()){
|
||||
url = url+"&"+"type=sub";
|
||||
}
|
||||
|
||||
if(this.remoteTableSkipProfileRestriction()){
|
||||
url = url+"&"+"skip=1";
|
||||
}
|
||||
|
||||
return url;
|
||||
});
|
||||
|
||||
AdapterBase.method('isSubProfileTable', function() {
|
||||
return false;
|
||||
});
|
||||
|
||||
AdapterBase.method('remoteTableSkipProfileRestriction', function() {
|
||||
return false;
|
||||
});
|
||||
|
||||
AdapterBase.method('preProcessTableData', function(row) {
|
||||
return row;
|
||||
});
|
||||
|
||||
AdapterBase.method('getSuccessCallBack', function(callBackData,serverData) {
|
||||
var data = [];
|
||||
var mapping = this.getDataMapping();
|
||||
for(var i=0;i<serverData.length;i++){
|
||||
var row = [];
|
||||
for(var j=0;j<mapping.length;j++){
|
||||
row[j] = serverData[i][mapping[j]];
|
||||
}
|
||||
data.push(this.preProcessTableData(row));
|
||||
}
|
||||
this.sourceData = serverData;
|
||||
if(callBackData['callBack']!= undefined && callBackData['callBack'] != null){
|
||||
if(callBackData['callBackData'] == undefined || callBackData['callBackData'] == null){
|
||||
callBackData['callBackData'] = new Array();
|
||||
}
|
||||
callBackData['callBackData'].push(serverData);
|
||||
callBackData['callBackData'].push(data);
|
||||
this.callFunction(callBackData['callBack'],callBackData['callBackData']);
|
||||
}
|
||||
|
||||
this.tableData = data;
|
||||
|
||||
if(callBackData['noRender']!= undefined && callBackData['noRender'] != null && callBackData['noRender'] == true){
|
||||
|
||||
}else{
|
||||
this.createTable(this.getTableName());
|
||||
$("#"+this.getTableName()+'Form').hide();
|
||||
$("#"+this.getTableName()).show();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
AdapterBase.method('getFailCallBack', function(callBackData,serverData) {
|
||||
|
||||
});
|
||||
|
||||
|
||||
AdapterBase.method('getElement', function(id,callBackData) {
|
||||
var that = this;
|
||||
var sourceMappingJson = JSON.stringify(this.getSourceMapping());
|
||||
sourceMappingJson = this.fixJSON(sourceMappingJson);
|
||||
$.post(this.moduleRelativeURL, {'t':this.table,'a':'getElement','id':id,'sm':sourceMappingJson}, function(data) {
|
||||
if(data.status == "SUCCESS"){
|
||||
that.getElementSuccessCallBack.apply(that,[callBackData,data.object]);
|
||||
}else{
|
||||
that.getElementFailCallBack.apply(that,[callBackData,data.object]);
|
||||
}
|
||||
},"json");
|
||||
this.trackEvent("getElement",this.tab,this.table);
|
||||
});
|
||||
|
||||
AdapterBase.method('getElementSuccessCallBack', function(callBackData,serverData) {
|
||||
if(callBackData['callBack']!= undefined && callBackData['callBack'] != null){
|
||||
if(callBackData['callBackData'] == undefined || callBackData['callBackData'] == null){
|
||||
callBackData['callBackData'] = new Array();
|
||||
}
|
||||
callBackData['callBackData'].push(serverData);
|
||||
this.callFunction(callBackData['callBack'],callBackData['callBackData'],this);
|
||||
}
|
||||
this.currentElement = serverData;
|
||||
if(callBackData['noRender']!= undefined && callBackData['noRender'] != null && callBackData['noRender'] == true){
|
||||
|
||||
}else{
|
||||
this.renderForm(serverData);
|
||||
}
|
||||
});
|
||||
|
||||
AdapterBase.method('getElementFailCallBack', function(callBackData,serverData) {
|
||||
|
||||
});
|
||||
|
||||
|
||||
AdapterBase.method('getTableData', function() {
|
||||
return this.tableData;
|
||||
});
|
||||
|
||||
AdapterBase.method('getTableName', function() {
|
||||
return this.tab;
|
||||
});
|
||||
|
||||
AdapterBase.method('getFieldValues', function(fieldMaster,callBackData) {
|
||||
var that = this;
|
||||
var method = "";
|
||||
var methodParams = "";
|
||||
if(fieldMaster[3] != undefined && fieldMaster[3] != null){
|
||||
method = fieldMaster[3];
|
||||
}
|
||||
|
||||
if(fieldMaster[4] != undefined && fieldMaster[4] != null){
|
||||
methodParams = JSON.stringify(fieldMaster[4]);
|
||||
}
|
||||
|
||||
var key = this.requestCache.getKey(this.moduleRelativeURL,{'t':fieldMaster[0],'key':fieldMaster[1],'value':fieldMaster[2],'method':method,'methodParams':methodParams,'a':'getFieldValues'});
|
||||
var cacheData = this.requestCache.getData(key);
|
||||
|
||||
if(cacheData != null){
|
||||
|
||||
if(cacheData.status == "SUCCESS"){
|
||||
callBackData['callBackData'].push(cacheData.data);
|
||||
if(callBackData['callBackSuccess'] != null && callBackData['callBackSuccess'] != undefined){
|
||||
callBackData['callBackData'].push(callBackData['callBackSuccess']);
|
||||
}
|
||||
that.callFunction(callBackData['callBack'],callBackData['callBackData']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var callbackWraper = function(data) {
|
||||
if(data.status == "SUCCESS"){
|
||||
that.requestCache.setData(this.success.key, data);
|
||||
callBackData['callBackData'].push(data.data);
|
||||
if(callBackData['callBackSuccess'] != null && callBackData['callBackSuccess'] != undefined){
|
||||
callBackData['callBackData'].push(callBackData['callBackSuccess']);
|
||||
}
|
||||
that.callFunction(callBackData['callBack'],callBackData['callBackData']);
|
||||
}
|
||||
};
|
||||
|
||||
callbackWraper.key = key;
|
||||
|
||||
$.post(this.moduleRelativeURL, {'t':fieldMaster[0],'key':fieldMaster[1],'value':fieldMaster[2],'method':method,'methodParams':methodParams,'a':'getFieldValues'}, callbackWraper,"json");
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
AdapterBase.method('setAdminProfile', function(empId) {
|
||||
var that = this;
|
||||
$.post(this.moduleRelativeURL, {'a':'setAdminEmp','empid':empId}, function(data) {
|
||||
top.location.href = clientUrl;
|
||||
},"json");
|
||||
});
|
||||
|
||||
AdapterBase.method('customAction', function(subAction,module,request,callBackData) {
|
||||
var that = this;
|
||||
request = this.fixJSON(request);
|
||||
$.getJSON(this.moduleRelativeURL, {'t':this.table,'a':'ca','sa':subAction,'mod':module,'req':request}, function(data) {
|
||||
if(data.status == "SUCCESS"){
|
||||
callBackData['callBackData'].push(data.data);
|
||||
that.callFunction(callBackData['callBackSuccess'],callBackData['callBackData']);
|
||||
}else{
|
||||
callBackData['callBackData'].push(data.data);
|
||||
that.callFunction(callBackData['callBackFail'],callBackData['callBackData']);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
AdapterBase.method('sendCustomRequest', function(action,params,successCallback,failCallback) {
|
||||
var that = this;
|
||||
params['a'] = action;
|
||||
$.post(this.moduleRelativeURL, params, function(data) {
|
||||
if(data.status == "SUCCESS"){
|
||||
successCallback(data['data']);
|
||||
}else{
|
||||
failCallback(data['data']);
|
||||
}
|
||||
},"json");
|
||||
});
|
||||
|
||||
|
||||
AdapterBase.method('getCustomActionUrl', function(action,params) {
|
||||
|
||||
params['a'] = action;
|
||||
var str = "";
|
||||
for(var key in params){
|
||||
if(params.hasOwnProperty(key)){
|
||||
if(str != ""){
|
||||
str += "&";
|
||||
}
|
||||
str += key + "=" + params[key];
|
||||
}
|
||||
}
|
||||
return this.moduleRelativeURL+"?"+str;
|
||||
});
|
||||
|
||||
|
||||
AdapterBase.method('getClientDataUrl', function() {
|
||||
return this.moduleRelativeURL.replace("service.php","")+"data/";
|
||||
});
|
||||
|
||||
AdapterBase.method('getCustomUrl', function(str) {
|
||||
return this.moduleRelativeURL.replace("service.php",str);
|
||||
});
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @class SubAdapterBase
|
||||
* @param endPoint
|
||||
* @param tab
|
||||
* @param filter
|
||||
* @param orderBy
|
||||
* @returns
|
||||
*/
|
||||
|
||||
|
||||
function SubAdapterBase(endPoint,tab,filter,orderBy) {
|
||||
this.initAdapter(endPoint,tab,filter,orderBy);
|
||||
}
|
||||
|
||||
SubAdapterBase.inherits(AdapterBase);
|
||||
|
||||
SubAdapterBase.method('deleteRow', function(id) {
|
||||
this.deleteParams['id'] = id;
|
||||
this.confirmDelete();
|
||||
});
|
||||
|
||||
SubAdapterBase.method('createTable', function(elementId) {
|
||||
var item, itemHtml,itemDelete,itemEdit;
|
||||
var data = this.getTableData();
|
||||
|
||||
var deleteButton = '<button id="#_id_#_delete" onclick="modJs.subModJsList[\'tab'+elementId+'\'].deleteRow(\'_id_\');return false;" type="button" style="position: absolute;bottom: 5px;right: 5px;font-size: 13px;" tooltip="Delete"><li class="fa fa-times"></li></button>';
|
||||
var editButton = '<button id="#_id_#_edit" onclick="modJs.subModJsList[\'tab'+elementId+'\'].edit(\'_id_\');return false;" type="button" style="position: absolute;bottom: 5px;right: 35px;font-size: 13px;" tooltip="Edit"><li class="fa fa-edit"></li></button>';
|
||||
|
||||
var table = $('<div class="list-group"></div>');
|
||||
|
||||
//add Header
|
||||
var header = this.getSubHeader();
|
||||
table.append(header);
|
||||
if(data.length == 0){
|
||||
table.append('<a href="#" class="list-group-item">'+this.getNoDataMessage()+'</a>');
|
||||
}else{
|
||||
for(var i=0;i<data.length;i++){
|
||||
item = data[i];
|
||||
itemDelete = deleteButton.replace(/_id_/g,item[0]);
|
||||
itemEdit = editButton.replace(/_id_/g,item[0]);
|
||||
itemHtml = this.getSubItemHtml(item,itemDelete,itemEdit);
|
||||
table.append(itemHtml);
|
||||
}
|
||||
|
||||
}
|
||||
$("#"+elementId).html("");
|
||||
$("#"+elementId).append(table);
|
||||
$('#plainMessageModel').modal('hide');
|
||||
|
||||
});
|
||||
|
||||
SubAdapterBase.method('getNoDataMessage', function() {
|
||||
return "No data found";
|
||||
});
|
||||
|
||||
SubAdapterBase.method('getSubHeader', function() {
|
||||
var header = $('<a href="#" onclick="return false;" class="list-group-item" style="background:#eee;"><h4 class="list-group-item-heading">'+this.getSubHeaderTitle()+'</h4></a>');
|
||||
return header;
|
||||
});
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* IdNameAdapter
|
||||
*/
|
||||
|
||||
function IdNameAdapter(endPoint) {
|
||||
this.initAdapter(endPoint);
|
||||
}
|
||||
|
||||
IdNameAdapter.inherits(AdapterBase);
|
||||
|
||||
|
||||
|
||||
IdNameAdapter.method('getDataMapping', function() {
|
||||
return [
|
||||
"id",
|
||||
"name"
|
||||
];
|
||||
});
|
||||
|
||||
IdNameAdapter.method('getHeaders', function() {
|
||||
return [
|
||||
{ "sTitle": "ID" ,"bVisible":false},
|
||||
{ "sTitle": "Name"}
|
||||
];
|
||||
});
|
||||
|
||||
IdNameAdapter.method('getFormFields', function() {
|
||||
return [
|
||||
[ "id", {"label":"ID","type":"hidden"}],
|
||||
[ "name", {"label":"Name","type":"text","validation":""}]
|
||||
];
|
||||
});
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* RequestCache
|
||||
*/
|
||||
|
||||
function RequestCache() {
|
||||
|
||||
}
|
||||
|
||||
RequestCache.method('getKey', function(url,params) {
|
||||
var key = url+"|";
|
||||
for(index in params){
|
||||
key += index+"="+params[index]+"|";
|
||||
}
|
||||
return key;
|
||||
});
|
||||
|
||||
RequestCache.method('getData', function(key) {
|
||||
var data;
|
||||
if (typeof(Storage) == "undefined") {
|
||||
return null;
|
||||
}
|
||||
|
||||
var strData = localStorage.getItem(key);
|
||||
if(strData != undefined && strData != null && strData != ""){
|
||||
return JSON.parse(strData);
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
RequestCache.method('setData', function(key, data) {
|
||||
|
||||
if (typeof(Storage) == "undefined") {
|
||||
return null;
|
||||
}
|
||||
|
||||
var strData = JSON.stringify(data);
|
||||
var strData = localStorage.setItem(key,strData);
|
||||
return strData;
|
||||
});
|
||||
503
src/api/AesCrypt.js
Normal file
503
src/api/AesCrypt.js
Normal file
@@ -0,0 +1,503 @@
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
/* AES implementation in JavaScript (c) Chris Veness 2005-2014 / MIT Licence */
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
/* jshint node:true *//* global define */
|
||||
'use strict';
|
||||
|
||||
|
||||
/**
|
||||
* AES (Rijndael cipher) encryption routines,
|
||||
*
|
||||
* Reference implementation of FIPS-197 http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf.
|
||||
*
|
||||
* @namespace
|
||||
*/
|
||||
var Aes = {};
|
||||
|
||||
|
||||
/**
|
||||
* AES Cipher function: encrypt 'input' state with Rijndael algorithm [§5.1];
|
||||
* applies Nr rounds (10/12/14) using key schedule w for 'add round key' stage.
|
||||
*
|
||||
* @param {number[]} input - 16-byte (128-bit) input state array.
|
||||
* @param {number[][]} w - Key schedule as 2D byte-array (Nr+1 x Nb bytes).
|
||||
* @returns {number[]} Encrypted output state array.
|
||||
*/
|
||||
Aes.cipher = function(input, w) {
|
||||
var Nb = 4; // block size (in words): no of columns in state (fixed at 4 for AES)
|
||||
var Nr = w.length/Nb - 1; // no of rounds: 10/12/14 for 128/192/256-bit keys
|
||||
|
||||
var state = [[],[],[],[]]; // initialise 4xNb byte-array 'state' with input [§3.4]
|
||||
for (var i=0; i<4*Nb; i++) state[i%4][Math.floor(i/4)] = input[i];
|
||||
|
||||
state = Aes.addRoundKey(state, w, 0, Nb);
|
||||
|
||||
for (var round=1; round<Nr; round++) {
|
||||
state = Aes.subBytes(state, Nb);
|
||||
state = Aes.shiftRows(state, Nb);
|
||||
state = Aes.mixColumns(state, Nb);
|
||||
state = Aes.addRoundKey(state, w, round, Nb);
|
||||
}
|
||||
|
||||
state = Aes.subBytes(state, Nb);
|
||||
state = Aes.shiftRows(state, Nb);
|
||||
state = Aes.addRoundKey(state, w, Nr, Nb);
|
||||
|
||||
var output = new Array(4*Nb); // convert state to 1-d array before returning [§3.4]
|
||||
for (var i=0; i<4*Nb; i++) output[i] = state[i%4][Math.floor(i/4)];
|
||||
|
||||
return output;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Perform key expansion to generate a key schedule from a cipher key [§5.2].
|
||||
*
|
||||
* @param {number[]} key - Cipher key as 16/24/32-byte array.
|
||||
* @returns {number[][]} Expanded key schedule as 2D byte-array (Nr+1 x Nb bytes).
|
||||
*/
|
||||
Aes.keyExpansion = function(key) {
|
||||
var Nb = 4; // block size (in words): no of columns in state (fixed at 4 for AES)
|
||||
var Nk = key.length/4; // key length (in words): 4/6/8 for 128/192/256-bit keys
|
||||
var Nr = Nk + 6; // no of rounds: 10/12/14 for 128/192/256-bit keys
|
||||
|
||||
var w = new Array(Nb*(Nr+1));
|
||||
var temp = new Array(4);
|
||||
|
||||
// initialise first Nk words of expanded key with cipher key
|
||||
for (var i=0; i<Nk; i++) {
|
||||
var r = [key[4*i], key[4*i+1], key[4*i+2], key[4*i+3]];
|
||||
w[i] = r;
|
||||
}
|
||||
|
||||
// expand the key into the remainder of the schedule
|
||||
for (var i=Nk; i<(Nb*(Nr+1)); i++) {
|
||||
w[i] = new Array(4);
|
||||
for (var t=0; t<4; t++) temp[t] = w[i-1][t];
|
||||
// each Nk'th word has extra transformation
|
||||
if (i % Nk == 0) {
|
||||
temp = Aes.subWord(Aes.rotWord(temp));
|
||||
for (var t=0; t<4; t++) temp[t] ^= Aes.rCon[i/Nk][t];
|
||||
}
|
||||
// 256-bit key has subWord applied every 4th word
|
||||
else if (Nk > 6 && i%Nk == 4) {
|
||||
temp = Aes.subWord(temp);
|
||||
}
|
||||
// xor w[i] with w[i-1] and w[i-Nk]
|
||||
for (var t=0; t<4; t++) w[i][t] = w[i-Nk][t] ^ temp[t];
|
||||
}
|
||||
|
||||
return w;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Apply SBox to state S [§5.1.1]
|
||||
* @private
|
||||
*/
|
||||
Aes.subBytes = function(s, Nb) {
|
||||
for (var r=0; r<4; r++) {
|
||||
for (var c=0; c<Nb; c++) s[r][c] = Aes.sBox[s[r][c]];
|
||||
}
|
||||
return s;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Shift row r of state S left by r bytes [§5.1.2]
|
||||
* @private
|
||||
*/
|
||||
Aes.shiftRows = function(s, Nb) {
|
||||
var t = new Array(4);
|
||||
for (var r=1; r<4; r++) {
|
||||
for (var c=0; c<4; c++) t[c] = s[r][(c+r)%Nb]; // shift into temp copy
|
||||
for (var c=0; c<4; c++) s[r][c] = t[c]; // and copy back
|
||||
} // note that this will work for Nb=4,5,6, but not 7,8 (always 4 for AES):
|
||||
return s; // see asmaes.sourceforge.net/rijndael/rijndaelImplementation.pdf
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Combine bytes of each col of state S [§5.1.3]
|
||||
* @private
|
||||
*/
|
||||
Aes.mixColumns = function(s, Nb) {
|
||||
for (var c=0; c<4; c++) {
|
||||
var a = new Array(4); // 'a' is a copy of the current column from 's'
|
||||
var b = new Array(4); // 'b' is a•{02} in GF(2^8)
|
||||
for (var i=0; i<4; i++) {
|
||||
a[i] = s[i][c];
|
||||
b[i] = s[i][c]&0x80 ? s[i][c]<<1 ^ 0x011b : s[i][c]<<1;
|
||||
}
|
||||
// a[n] ^ b[n] is a•{03} in GF(2^8)
|
||||
s[0][c] = b[0] ^ a[1] ^ b[1] ^ a[2] ^ a[3]; // {02}•a0 + {03}•a1 + a2 + a3
|
||||
s[1][c] = a[0] ^ b[1] ^ a[2] ^ b[2] ^ a[3]; // a0 • {02}•a1 + {03}•a2 + a3
|
||||
s[2][c] = a[0] ^ a[1] ^ b[2] ^ a[3] ^ b[3]; // a0 + a1 + {02}•a2 + {03}•a3
|
||||
s[3][c] = a[0] ^ b[0] ^ a[1] ^ a[2] ^ b[3]; // {03}•a0 + a1 + a2 + {02}•a3
|
||||
}
|
||||
return s;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Xor Round Key into state S [§5.1.4]
|
||||
* @private
|
||||
*/
|
||||
Aes.addRoundKey = function(state, w, rnd, Nb) {
|
||||
for (var r=0; r<4; r++) {
|
||||
for (var c=0; c<Nb; c++) state[r][c] ^= w[rnd*4+c][r];
|
||||
}
|
||||
return state;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Apply SBox to 4-byte word w
|
||||
* @private
|
||||
*/
|
||||
Aes.subWord = function(w) {
|
||||
for (var i=0; i<4; i++) w[i] = Aes.sBox[w[i]];
|
||||
return w;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Rotate 4-byte word w left by one byte
|
||||
* @private
|
||||
*/
|
||||
Aes.rotWord = function(w) {
|
||||
var tmp = w[0];
|
||||
for (var i=0; i<3; i++) w[i] = w[i+1];
|
||||
w[3] = tmp;
|
||||
return w;
|
||||
};
|
||||
|
||||
|
||||
// sBox is pre-computed multiplicative inverse in GF(2^8) used in subBytes and keyExpansion [§5.1.1]
|
||||
Aes.sBox = [0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,
|
||||
0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,
|
||||
0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15,
|
||||
0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,
|
||||
0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,
|
||||
0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf,
|
||||
0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8,
|
||||
0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2,
|
||||
0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73,
|
||||
0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb,
|
||||
0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79,
|
||||
0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08,
|
||||
0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a,
|
||||
0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e,
|
||||
0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf,
|
||||
0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16];
|
||||
|
||||
|
||||
// rCon is Round Constant used for the Key Expansion [1st col is 2^(r-1) in GF(2^8)] [§5.2]
|
||||
Aes.rCon = [ [0x00, 0x00, 0x00, 0x00],
|
||||
[0x01, 0x00, 0x00, 0x00],
|
||||
[0x02, 0x00, 0x00, 0x00],
|
||||
[0x04, 0x00, 0x00, 0x00],
|
||||
[0x08, 0x00, 0x00, 0x00],
|
||||
[0x10, 0x00, 0x00, 0x00],
|
||||
[0x20, 0x00, 0x00, 0x00],
|
||||
[0x40, 0x00, 0x00, 0x00],
|
||||
[0x80, 0x00, 0x00, 0x00],
|
||||
[0x1b, 0x00, 0x00, 0x00],
|
||||
[0x36, 0x00, 0x00, 0x00] ];
|
||||
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
if (typeof module != 'undefined' && module.exports) module.exports = Aes; // CommonJs export
|
||||
if (typeof define == 'function' && define.amd) define([], function() { return Aes; }); // AMD
|
||||
|
||||
|
||||
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
/* AES Counter-mode implementation in JavaScript (c) Chris Veness 2005-2014 / MIT Licence */
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
/* jshint node:true *//* global define, escape, unescape, btoa, atob */
|
||||
'use strict';
|
||||
if (typeof module!='undefined' && module.exports) var Aes = require('./aes'); // CommonJS (Node.js)
|
||||
|
||||
|
||||
/**
|
||||
* Aes.Ctr: Counter-mode (CTR) wrapper for AES.
|
||||
*
|
||||
* This encrypts a Unicode string to produces a base64 ciphertext using 128/192/256-bit AES,
|
||||
* and the converse to decrypt an encrypted ciphertext.
|
||||
*
|
||||
* See http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
|
||||
*
|
||||
* @augments Aes
|
||||
*/
|
||||
Aes.Ctr = {};
|
||||
|
||||
|
||||
/**
|
||||
* Encrypt a text using AES encryption in Counter mode of operation.
|
||||
*
|
||||
* Unicode multi-byte character safe
|
||||
*
|
||||
* @param {string} plaintext - Source text to be encrypted.
|
||||
* @param {string} password - The password to use to generate a key.
|
||||
* @param {number} nBits - Number of bits to be used in the key; 128 / 192 / 256.
|
||||
* @returns {string} Encrypted text.
|
||||
*
|
||||
* @example
|
||||
* var encr = Aes.Ctr.encrypt('big secret', 'pāşšŵōřđ', 256); // encr: 'lwGl66VVwVObKIr6of8HVqJr'
|
||||
*/
|
||||
Aes.Ctr.encrypt = function(plaintext, password, nBits) {
|
||||
var blockSize = 16; // block size fixed at 16 bytes / 128 bits (Nb=4) for AES
|
||||
if (!(nBits==128 || nBits==192 || nBits==256)) return ''; // standard allows 128/192/256 bit keys
|
||||
plaintext = String(plaintext).utf8Encode();
|
||||
password = String(password).utf8Encode();
|
||||
|
||||
// use AES itself to encrypt password to get cipher key (using plain password as source for key
|
||||
// expansion) - gives us well encrypted key (though hashed key might be preferred for prod'n use)
|
||||
var nBytes = nBits/8; // no bytes in key (16/24/32)
|
||||
var pwBytes = new Array(nBytes);
|
||||
for (var i=0; i<nBytes; i++) { // use 1st 16/24/32 chars of password for key
|
||||
pwBytes[i] = isNaN(password.charCodeAt(i)) ? 0 : password.charCodeAt(i);
|
||||
}
|
||||
var key = Aes.cipher(pwBytes, Aes.keyExpansion(pwBytes)); // gives us 16-byte key
|
||||
key = key.concat(key.slice(0, nBytes-16)); // expand key to 16/24/32 bytes long
|
||||
|
||||
// initialise 1st 8 bytes of counter block with nonce (NIST SP800-38A §B.2): [0-1] = millisec,
|
||||
// [2-3] = random, [4-7] = seconds, together giving full sub-millisec uniqueness up to Feb 2106
|
||||
var counterBlock = new Array(blockSize);
|
||||
|
||||
var nonce = (new Date()).getTime(); // timestamp: milliseconds since 1-Jan-1970
|
||||
var nonceMs = nonce%1000;
|
||||
var nonceSec = Math.floor(nonce/1000);
|
||||
var nonceRnd = Math.floor(Math.random()*0xffff);
|
||||
// for debugging: nonce = nonceMs = nonceSec = nonceRnd = 0;
|
||||
|
||||
for (var i=0; i<2; i++) counterBlock[i] = (nonceMs >>> i*8) & 0xff;
|
||||
for (var i=0; i<2; i++) counterBlock[i+2] = (nonceRnd >>> i*8) & 0xff;
|
||||
for (var i=0; i<4; i++) counterBlock[i+4] = (nonceSec >>> i*8) & 0xff;
|
||||
|
||||
// and convert it to a string to go on the front of the ciphertext
|
||||
var ctrTxt = '';
|
||||
for (var i=0; i<8; i++) ctrTxt += String.fromCharCode(counterBlock[i]);
|
||||
|
||||
// generate key schedule - an expansion of the key into distinct Key Rounds for each round
|
||||
var keySchedule = Aes.keyExpansion(key);
|
||||
|
||||
var blockCount = Math.ceil(plaintext.length/blockSize);
|
||||
var ciphertxt = new Array(blockCount); // ciphertext as array of strings
|
||||
|
||||
for (var b=0; b<blockCount; b++) {
|
||||
// set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes)
|
||||
// done in two stages for 32-bit ops: using two words allows us to go past 2^32 blocks (68GB)
|
||||
for (var c=0; c<4; c++) counterBlock[15-c] = (b >>> c*8) & 0xff;
|
||||
for (var c=0; c<4; c++) counterBlock[15-c-4] = (b/0x100000000 >>> c*8);
|
||||
|
||||
var cipherCntr = Aes.cipher(counterBlock, keySchedule); // -- encrypt counter block --
|
||||
|
||||
// block size is reduced on final block
|
||||
var blockLength = b<blockCount-1 ? blockSize : (plaintext.length-1)%blockSize+1;
|
||||
var cipherChar = new Array(blockLength);
|
||||
|
||||
for (var i=0; i<blockLength; i++) { // -- xor plaintext with ciphered counter char-by-char --
|
||||
cipherChar[i] = cipherCntr[i] ^ plaintext.charCodeAt(b*blockSize+i);
|
||||
cipherChar[i] = String.fromCharCode(cipherChar[i]);
|
||||
}
|
||||
ciphertxt[b] = cipherChar.join('');
|
||||
}
|
||||
|
||||
// use Array.join() for better performance than repeated string appends
|
||||
var ciphertext = ctrTxt + ciphertxt.join('');
|
||||
ciphertext = ciphertext.base64Encode();
|
||||
|
||||
return ciphertext;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Decrypt a text encrypted by AES in counter mode of operation
|
||||
*
|
||||
* @param {string} ciphertext - Source text to be encrypted.
|
||||
* @param {string} password - Password to use to generate a key.
|
||||
* @param {number} nBits - Number of bits to be used in the key; 128 / 192 / 256.
|
||||
* @returns {string} Decrypted text
|
||||
*
|
||||
* @example
|
||||
* var decr = Aes.Ctr.encrypt('lwGl66VVwVObKIr6of8HVqJr', 'pāşšŵōřđ', 256); // decr: 'big secret'
|
||||
*/
|
||||
Aes.Ctr.decrypt = function(ciphertext, password, nBits) {
|
||||
var blockSize = 16; // block size fixed at 16 bytes / 128 bits (Nb=4) for AES
|
||||
if (!(nBits==128 || nBits==192 || nBits==256)) return ''; // standard allows 128/192/256 bit keys
|
||||
ciphertext = String(ciphertext).base64Decode();
|
||||
password = String(password).utf8Encode();
|
||||
|
||||
// use AES to encrypt password (mirroring encrypt routine)
|
||||
var nBytes = nBits/8; // no bytes in key
|
||||
var pwBytes = new Array(nBytes);
|
||||
for (var i=0; i<nBytes; i++) {
|
||||
pwBytes[i] = isNaN(password.charCodeAt(i)) ? 0 : password.charCodeAt(i);
|
||||
}
|
||||
var key = Aes.cipher(pwBytes, Aes.keyExpansion(pwBytes));
|
||||
key = key.concat(key.slice(0, nBytes-16)); // expand key to 16/24/32 bytes long
|
||||
|
||||
// recover nonce from 1st 8 bytes of ciphertext
|
||||
var counterBlock = new Array(8);
|
||||
var ctrTxt = ciphertext.slice(0, 8);
|
||||
for (var i=0; i<8; i++) counterBlock[i] = ctrTxt.charCodeAt(i);
|
||||
|
||||
// generate key schedule
|
||||
var keySchedule = Aes.keyExpansion(key);
|
||||
|
||||
// separate ciphertext into blocks (skipping past initial 8 bytes)
|
||||
var nBlocks = Math.ceil((ciphertext.length-8) / blockSize);
|
||||
var ct = new Array(nBlocks);
|
||||
for (var b=0; b<nBlocks; b++) ct[b] = ciphertext.slice(8+b*blockSize, 8+b*blockSize+blockSize);
|
||||
ciphertext = ct; // ciphertext is now array of block-length strings
|
||||
|
||||
// plaintext will get generated block-by-block into array of block-length strings
|
||||
var plaintxt = new Array(ciphertext.length);
|
||||
|
||||
for (var b=0; b<nBlocks; b++) {
|
||||
// set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes)
|
||||
for (var c=0; c<4; c++) counterBlock[15-c] = ((b) >>> c*8) & 0xff;
|
||||
for (var c=0; c<4; c++) counterBlock[15-c-4] = (((b+1)/0x100000000-1) >>> c*8) & 0xff;
|
||||
|
||||
var cipherCntr = Aes.cipher(counterBlock, keySchedule); // encrypt counter block
|
||||
|
||||
var plaintxtByte = new Array(ciphertext[b].length);
|
||||
for (var i=0; i<ciphertext[b].length; i++) {
|
||||
// -- xor plaintxt with ciphered counter byte-by-byte --
|
||||
plaintxtByte[i] = cipherCntr[i] ^ ciphertext[b].charCodeAt(i);
|
||||
plaintxtByte[i] = String.fromCharCode(plaintxtByte[i]);
|
||||
}
|
||||
plaintxt[b] = plaintxtByte.join('');
|
||||
}
|
||||
|
||||
// join array of blocks into single plaintext string
|
||||
var plaintext = plaintxt.join('');
|
||||
plaintext = plaintext.utf8Decode(); // decode from UTF8 back to Unicode multi-byte chars
|
||||
|
||||
return plaintext;
|
||||
};
|
||||
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
/** Extend String object with method to encode multi-byte string to utf8
|
||||
* - monsur.hossa.in/2012/07/20/utf-8-in-javascript.html */
|
||||
if (typeof String.prototype.utf8Encode == 'undefined') {
|
||||
String.prototype.utf8Encode = function() {
|
||||
return unescape( encodeURIComponent( this ) );
|
||||
};
|
||||
}
|
||||
|
||||
/** Extend String object with method to decode utf8 string to multi-byte */
|
||||
if (typeof String.prototype.utf8Decode == 'undefined') {
|
||||
String.prototype.utf8Decode = function() {
|
||||
try {
|
||||
return decodeURIComponent( escape( this ) );
|
||||
} catch (e) {
|
||||
return this; // invalid UTF-8? return as-is
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/** Extend String object with method to encode base64
|
||||
* - developer.mozilla.org/en-US/docs/Web/API/window.btoa, nodejs.org/api/buffer.html
|
||||
* note: if btoa()/atob() are not available (eg IE9-), try github.com/davidchambers/Base64.js */
|
||||
if (typeof String.prototype.base64Encode == 'undefined') {
|
||||
String.prototype.base64Encode = function() {
|
||||
if (typeof btoa != 'undefined') return btoa(this); // browser
|
||||
if (typeof Buffer != 'undefined') return new Buffer(this, 'utf8').toString('base64'); // Node.js
|
||||
throw new Error('No Base64 Encode');
|
||||
};
|
||||
}
|
||||
|
||||
/** Extend String object with method to decode base64 */
|
||||
if (typeof String.prototype.base64Decode == 'undefined') {
|
||||
String.prototype.base64Decode = function() {
|
||||
if (typeof atob != 'undefined') return atob(this); // browser
|
||||
if (typeof Buffer != 'undefined') return new Buffer(this, 'base64').toString('utf8'); // Node.js
|
||||
throw new Error('No Base64 Decode');
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
if (typeof module != 'undefined' && module.exports) module.exports = Aes.Ctr; // CommonJs export
|
||||
if (typeof define == 'function' && define.amd) define(['Aes'], function() { return Aes.Ctr; }); // AMD
|
||||
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
/* Encrypt/decrypt files */
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
function encryptFile(file) {
|
||||
// use FileReader.readAsArrayBuffer to handle binary files
|
||||
var reader = new FileReader();
|
||||
reader.readAsArrayBuffer(file);
|
||||
reader.onload = function(evt) {
|
||||
$('body').css({'cursor':'wait'});
|
||||
|
||||
// Aes.Ctr.encrypt expects a string, but converting binary file directly to string could
|
||||
// give invalid Unicode sequences, so convert bytestream ArrayBuffer to single-byte chars
|
||||
var contentBytes = new Uint8Array(reader.result); // ≡ evt.target.result
|
||||
var contentStr = '';
|
||||
for (var i=0; i<contentBytes.length; i++) {
|
||||
contentStr += String.fromCharCode(contentBytes[i]);
|
||||
}
|
||||
|
||||
var password = $('#password-file').val();
|
||||
|
||||
var t1 = new Date();
|
||||
var ciphertext = Aes.Ctr.encrypt(contentStr, password, 256);
|
||||
var t2 = new Date();
|
||||
|
||||
// use Blob to save encrypted file
|
||||
var blob = new Blob([ciphertext], { type: 'text/plain' });
|
||||
var filename = file.name+'.encrypted';
|
||||
saveAs(blob, filename);
|
||||
|
||||
$('#encrypt-file-time').html(((t2 - t1)/1000)+'s'); // display time taken
|
||||
$('body').css({'cursor':'default'});
|
||||
}
|
||||
}
|
||||
|
||||
function decryptFile(file) {
|
||||
// use FileReader.ReadAsText to read (base64-encoded) ciphertext file
|
||||
var reader = new FileReader();
|
||||
reader.readAsText(file);
|
||||
reader.onload = function(evt) {
|
||||
$('body').css({'cursor':'wait'});
|
||||
|
||||
var content = reader.result; // ≡ evt.target.result
|
||||
var password = $('#password-file').val();
|
||||
|
||||
var t1 = new Date();
|
||||
var plaintext = Aes.Ctr.decrypt(content, password, 256);
|
||||
var t2 = new Date();
|
||||
|
||||
// convert single-byte character stream to ArrayBuffer bytestream
|
||||
var contentBytes = new Uint8Array(plaintext.length);
|
||||
for (var i=0; i<plaintext.length; i++) {
|
||||
contentBytes[i] = plaintext.charCodeAt(i);
|
||||
}
|
||||
|
||||
// use Blob to save decrypted file
|
||||
var blob = new Blob([contentBytes], { type: 'application/octet-stream' });
|
||||
var filename = file.name.replace(/\.encrypted$/,'')+'.decrypted';
|
||||
saveAs(blob, filename);
|
||||
|
||||
$('#decrypt-file-time').html(((t2 - t1)/1000)+'s'); // display time taken
|
||||
$('body').css({'cursor':'default'});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
2052
src/api/Base.js
Normal file
2052
src/api/Base.js
Normal file
File diff suppressed because it is too large
Load Diff
270
src/api/FormValidation.js
Normal file
270
src/api/FormValidation.js
Normal file
@@ -0,0 +1,270 @@
|
||||
/*
|
||||
This file is part of Ice Framework.
|
||||
|
||||
Ice Framework is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Ice Framework is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Ice Framework. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
------------------------------------------------------------------
|
||||
|
||||
Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd]
|
||||
Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah)
|
||||
*/
|
||||
|
||||
function FormValidation(formId,validateAll,options) {
|
||||
this.tempOptions = {};
|
||||
this.formId = formId;
|
||||
this.formError = false;
|
||||
this.formObject = null;
|
||||
this.errorMessages = "";
|
||||
this.popupDialog = null;
|
||||
this.validateAll = validateAll;
|
||||
this.errorMap = new Array();
|
||||
|
||||
this.settings = {"thirdPartyPopup":null,"LabelErrorClass":false, "ShowPopup":true};
|
||||
|
||||
this.settings = jQuery.extend(this.settings,options);
|
||||
|
||||
this.inputTypes = new Array( "text", "radio", "checkbox", "file", "password", "select-one","select-multi", "textarea","fileupload");
|
||||
|
||||
this.validator = {
|
||||
|
||||
float: function (str) {
|
||||
var floatstr = /^[-+]?[0-9]+(\.[0-9]+)?$/;
|
||||
if (str != null && str.match(floatstr)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
number: function (str) {
|
||||
var numstr = /^[0-9]+$/;
|
||||
if (str != null && str.match(numstr)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
numberOrEmpty: function (str) {
|
||||
if(str == ""){
|
||||
return true;
|
||||
}
|
||||
var numstr = /^[0-9]+$/;
|
||||
if (str != null && str.match(numstr)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
email: function (str) {
|
||||
var emailPattern = /^\s*[\w\-\+_]+(\.[\w\-\+_]+)*\@[\w\-\+_]+\.[\w\-\+_]+(\.[\w\-\+_]+)*\s*$/;
|
||||
return str != null && emailPattern.test(str);
|
||||
},
|
||||
|
||||
emailOrEmpty: function (str) {
|
||||
if(str == ""){
|
||||
return true;
|
||||
}
|
||||
var emailPattern = /^\s*[\w\-\+_]+(\.[\w\-\+_]+)*\@[\w\-\+_]+\.[\w\-\+_]+(\.[\w\-\+_]+)*\s*$/;
|
||||
return str != null && emailPattern.test(str);
|
||||
},
|
||||
|
||||
username: function (str) {
|
||||
var username = /^[a-zA-Z0-9]+$/;
|
||||
return str != null && username.test(str);
|
||||
},
|
||||
|
||||
input: function (str) {
|
||||
if (str != null && str.length > 0) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
FormValidation.method('clearError' , function(formInput, overrideMessage) {
|
||||
var id = formInput.attr("id");
|
||||
$('#'+ this.formId +' #field_'+id).removeClass('error');
|
||||
$('#'+ this.formId +' #help_'+id).html('');
|
||||
});
|
||||
|
||||
FormValidation.method('addError' , function(formInput, overrideMessage) {
|
||||
this.formError = true;
|
||||
if(formInput.attr("message") != null) {
|
||||
this.errorMessages += (formInput.attr("message") + "\n");
|
||||
this.errorMap[formInput.attr("name")] = formInput.attr("message");
|
||||
}else{
|
||||
this.errorMap[formInput.attr("name")] = "";
|
||||
}
|
||||
|
||||
var id = formInput.attr("id");
|
||||
var validation = formInput.attr("validation");
|
||||
var message = formInput.attr("validation");
|
||||
$('#'+ this.formId +' #field_'+id).addClass('error');
|
||||
if(message == undefined || message == null || message == ""){
|
||||
$('#'+ this.formId +' #help_'+id).html(message);
|
||||
}else{
|
||||
if(validation == undefined || validation == null || validation == ""){
|
||||
$('#'+ this.formId +' #help_'+id).html("Required");
|
||||
}else{
|
||||
if(validation == "float" || validation == "number"){
|
||||
$('#'+ this.formId +' #help_'+id).html("Number required");
|
||||
}else if(validation == "email"){
|
||||
$('#'+ this.formId +' #help_'+id).html("Email required");
|
||||
}else{
|
||||
$('#'+ this.formId +' #help_'+id).html("Required");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
FormValidation.method('showErrors' , function() {
|
||||
if(this.formError) {
|
||||
if(this.settings['thirdPartyPopup'] != undefined && this.settings['thirdPartyPopup'] != null){
|
||||
this.settings['thirdPartyPopup'].alert();
|
||||
}else{
|
||||
if(this.settings['ShowPopup'] == true){
|
||||
if(this.tempOptions['popupTop'] != undefined && this.tempOptions['popupTop'] != null){
|
||||
this.alert("Errors Found",this.errorMessages,this.tempOptions['popupTop']);
|
||||
}else{
|
||||
this.alert("Errors Found",this.errorMessages,-1);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
FormValidation.method('checkValues' , function(options) {
|
||||
this.tempOptions = options;
|
||||
var that = this;
|
||||
this.formError = false;
|
||||
this.errorMessages = "";
|
||||
this.formObject = new Object();
|
||||
var validate = function (inputObject) {
|
||||
if(that.settings['LabelErrorClass'] != false){
|
||||
$("label[for='" + name + "']").removeClass(that.settings['LabelErrorClass']);
|
||||
}
|
||||
var id = inputObject.attr("id");
|
||||
var name = inputObject.attr("name");
|
||||
var type = inputObject.attr("type");
|
||||
|
||||
if(inputObject.hasClass('select2-focusser') || inputObject.hasClass('select2-input')){
|
||||
return true;
|
||||
}
|
||||
|
||||
if(jQuery.inArray(type, that.inputTypes ) >= 0) {
|
||||
if(inputObject.hasClass('uploadInput')){
|
||||
inputValue = inputObject.attr("val");
|
||||
//}else if(inputObject.hasClass('datetimeInput')){
|
||||
//inputValue = inputObject.getDate()+":00";
|
||||
}else{
|
||||
//inputValue = (type == "radio" || type == "checkbox")?$("input[name='" + name + "']:checked").val():inputObject.val();
|
||||
|
||||
inputValue = null;
|
||||
if(type == "radio" || type == "checkbox"){
|
||||
inputValue = $("input[name='" + name + "']:checked").val();
|
||||
}else if(inputObject.hasClass('select2Field')){
|
||||
if($('#'+id).select2('data') != null && $('#'+id).select2('data') != undefined){
|
||||
inputValue = $('#'+id).select2('data').id;
|
||||
}else{
|
||||
inputValue = "";
|
||||
}
|
||||
|
||||
}else if(inputObject.hasClass('select2Multi')){
|
||||
if($('#'+id).select2('data') != null && $('#'+id).select2('data') != undefined){
|
||||
inputValueObjects = $('#'+id).select2('data');
|
||||
inputValue = [];
|
||||
for(var i=0;i<inputValueObjects.length;i++){
|
||||
inputValue.push(inputValueObjects[i].id);
|
||||
}
|
||||
inputValue = JSON.stringify(inputValue);
|
||||
}else{
|
||||
inputValue = "";
|
||||
}
|
||||
}else{
|
||||
inputValue = inputObject.val();
|
||||
}
|
||||
}
|
||||
|
||||
var validation = inputObject.attr('validation');
|
||||
var valid = false;
|
||||
|
||||
if(validation != undefined && validation != null && that.validator[validation] != undefined && that.validator[validation] != null){
|
||||
valid = that.validator[validation](inputValue);
|
||||
|
||||
}else{
|
||||
|
||||
if(that.validateAll){
|
||||
if(validation != undefined && validation != null && validation == "none"){
|
||||
valid = true;
|
||||
}else{
|
||||
valid = that.validator['input'](inputValue);
|
||||
}
|
||||
|
||||
}else{
|
||||
valid = true;
|
||||
}
|
||||
$(that.formObject).attr(id,inputValue);
|
||||
}
|
||||
|
||||
if(!valid) {
|
||||
that.addError(inputObject, null);
|
||||
}else{
|
||||
that.clearError(inputObject, null);
|
||||
$(that.formObject).attr(id,inputValue);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
var inputs = $('#'+ this.formId + " :input");
|
||||
inputs.each(function() {
|
||||
var that = $(this);
|
||||
validate(that);
|
||||
});
|
||||
|
||||
inputs = $('#'+ this.formId + " .uploadInput");
|
||||
inputs.each(function() {
|
||||
var that = $(this);
|
||||
validate(that);
|
||||
});
|
||||
|
||||
this.showErrors();
|
||||
this.tempOptions = {};
|
||||
return !this.formError;
|
||||
});
|
||||
|
||||
FormValidation.method('getFormParameters' , function() {
|
||||
return this.formObject;
|
||||
});
|
||||
|
||||
|
||||
FormValidation.method('alert', function (title,text,top) {
|
||||
|
||||
alert(text);
|
||||
|
||||
});
|
||||
|
||||
|
||||
138
src/api/Notifications.js
Normal file
138
src/api/Notifications.js
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
This file is part of Ice Framework.
|
||||
|
||||
Ice Framework is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Ice Framework is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Ice Framework. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
------------------------------------------------------------------
|
||||
|
||||
Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd]
|
||||
Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah)
|
||||
*/
|
||||
|
||||
function NotificationManager() {
|
||||
this.baseUrl = "";
|
||||
this.templates = {};
|
||||
}
|
||||
|
||||
NotificationManager.method('setBaseUrl' , function(url) {
|
||||
this.baseUrl = url;
|
||||
});
|
||||
|
||||
NotificationManager.method('setTemplates' , function(data) {
|
||||
this.templates = data;
|
||||
});
|
||||
|
||||
NotificationManager.method('setTimeUtils' , function(timeUtils) {
|
||||
this.timeUtils = timeUtils;
|
||||
});
|
||||
|
||||
NotificationManager.method('getNotifications' , function(name, data) {
|
||||
var that = this;
|
||||
$.getJSON(this.baseUrl, {'a':'getNotifications'}, function(data) {
|
||||
if(data.status == "SUCCESS"){
|
||||
that.renderNotifications(data.data[1],data.data[0]);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
NotificationManager.method('clearPendingNotifications' , function(name, data) {
|
||||
var that = this;
|
||||
$.getJSON(this.baseUrl, {'a':'clearNotifications'}, function(data) {
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
NotificationManager.method('renderNotifications' , function(notifications, unreadCount) {
|
||||
|
||||
if(notifications.length == 0){
|
||||
return;
|
||||
}
|
||||
|
||||
var t = this.templates['notifications'];
|
||||
if(unreadCount > 0){
|
||||
t = t.replace('#_count_#',unreadCount);
|
||||
if(unreadCount > 1){
|
||||
t = t.replace('#_header_#',"You have "+unreadCount+" new notifications");
|
||||
}else{
|
||||
t = t.replace('#_header_#',"You have "+unreadCount+" new notification");
|
||||
}
|
||||
|
||||
}else{
|
||||
t = t.replace('#_count_#',"");
|
||||
t = t.replace('#_header_#',"You have no new notifications");
|
||||
}
|
||||
|
||||
var notificationStr = "";
|
||||
|
||||
for (index in notifications){
|
||||
notificationStr += this.renderNotification(notifications[index]);
|
||||
}
|
||||
|
||||
t = t.replace('#_notifications_#',notificationStr);
|
||||
|
||||
$obj = $(t);
|
||||
|
||||
if(unreadCount == 0){
|
||||
$obj.find('.label-danger').remove();
|
||||
}
|
||||
|
||||
$obj.attr("id","notifications");
|
||||
var k = $("#notifications");
|
||||
k.replaceWith($obj);
|
||||
|
||||
$(".navbar .menu").slimscroll({
|
||||
height: "320px",
|
||||
alwaysVisible: false,
|
||||
size: "3px"
|
||||
}).css("width", "100%");
|
||||
|
||||
this.timeUtils.convertToRelativeTime($(".notificationTime"));
|
||||
});
|
||||
|
||||
|
||||
NotificationManager.method('renderNotification' , function(notification) {
|
||||
var t = this.templates['notification'];
|
||||
t = t.replace('#_image_#',notification.image);
|
||||
|
||||
try{
|
||||
var json = JSON.parse(notification.action);
|
||||
t = t.replace('#_url_#',this.baseUrl.replace('service.php','?')+json['url']);
|
||||
}catch(e){
|
||||
t = t.replace('#_url_#',"");
|
||||
}
|
||||
|
||||
t = t.replace('#_time_#',notification.time);
|
||||
t = t.replace('#_fromName_#',notification.type);
|
||||
t = t.replace('#_message_#',this.getLineBreakString(notification.message,27));
|
||||
return t;
|
||||
});
|
||||
|
||||
|
||||
NotificationManager.method('getLineBreakString' , function(str, len) {
|
||||
var t = "";
|
||||
try{
|
||||
var arr = str.split(" ");
|
||||
var count = 0;
|
||||
for(var i=0;i<arr.length;i++){
|
||||
count += arr[i].length + 1;
|
||||
if(count > len){
|
||||
t += arr[i] + "<br/>";
|
||||
count = 0;
|
||||
}else{
|
||||
t += arr[i] + " ";
|
||||
}
|
||||
}
|
||||
}catch(e){}
|
||||
return t;
|
||||
});
|
||||
47
src/api/SocialShare.js
Normal file
47
src/api/SocialShare.js
Normal file
@@ -0,0 +1,47 @@
|
||||
function SocialShare(){
|
||||
};
|
||||
|
||||
SocialShare.facebook = function(url) {
|
||||
var w = 700;
|
||||
var h = 500;
|
||||
var left = (screen.width/2)-(w/2);
|
||||
var top = (screen.height/2)-(h/2);
|
||||
|
||||
var url = "https://www.facebook.com/sharer/sharer.php?u="+encodeURIComponent(url);
|
||||
|
||||
window.open(url, "Share on Facebook", "width="+w+",height="+h+",left="+left+",top="+top);
|
||||
return false;
|
||||
|
||||
};
|
||||
|
||||
SocialShare.google = function(url) {
|
||||
var w = 500;
|
||||
var h = 500;
|
||||
var left = (screen.width/2)-(w/2);
|
||||
var top = (screen.height/2)-(h/2);
|
||||
|
||||
var url = "https://plus.google.com/share?url="+encodeURIComponent(url);
|
||||
|
||||
window.open(url, "Share on Google", "width="+w+",height="+h+",left="+left+",top="+top);
|
||||
return false;
|
||||
|
||||
};
|
||||
|
||||
SocialShare.linkedin = function(url) {
|
||||
var w = 500;
|
||||
var h = 500;
|
||||
var left = (screen.width/2)-(w/2);
|
||||
var top = (screen.height/2)-(h/2);
|
||||
|
||||
var url = "https://www.linkedin.com/cws/share?url="+encodeURIComponent(url);
|
||||
|
||||
window.open(url, "Share on Linked in", "width="+w+",height="+h+",left="+left+",top="+top);
|
||||
return false;
|
||||
|
||||
};
|
||||
|
||||
SocialShare.twitter = function(url, msg) {
|
||||
window.open('http://twitter.com/share?text='+escape(msg) + '&url=' + escape(url),'popup','width=550,height=260,scrollbars=yes,resizable=yes,toolbar=no,directories=no,location=no,menubar=no,status=no,left=200,top=200');
|
||||
return false;
|
||||
|
||||
};
|
||||
152
src/api/TimeUtils.js
Normal file
152
src/api/TimeUtils.js
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
This file is part of Ice Framework.
|
||||
|
||||
Ice Framework is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Ice Framework is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Ice Framework. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
------------------------------------------------------------------
|
||||
|
||||
Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd]
|
||||
Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah)
|
||||
*/
|
||||
|
||||
function TimeUtils() {
|
||||
|
||||
}
|
||||
|
||||
TimeUtils.method('setServerGMToffset' , function(serverGMToffset) {
|
||||
this.serverGMToffset = serverGMToffset;
|
||||
});
|
||||
|
||||
TimeUtils.method('convertToRelativeTime',function(selector) {
|
||||
|
||||
var that = this;
|
||||
|
||||
var getAmPmTime = function(curHour, curMin) {
|
||||
var amPm = "am";
|
||||
var amPmHour = curHour;
|
||||
if (amPmHour >= 12) {
|
||||
amPm = "pm";
|
||||
if (amPmHour > 12) {
|
||||
amPmHour = amPmHour - 12;
|
||||
}
|
||||
}
|
||||
var prefixCurMin = "";
|
||||
if (curMin < 10) {
|
||||
prefixCurMin = "0";
|
||||
}
|
||||
|
||||
var prefixCurHour = "";
|
||||
if (curHour == 0) {
|
||||
prefixCurHour = "0";
|
||||
}
|
||||
return " at " + prefixCurHour + amPmHour + ":" + prefixCurMin + curMin + amPm;
|
||||
};
|
||||
|
||||
var getBrowserTimeZone = function() {
|
||||
var current_date = new Date();
|
||||
var gmt_offset = current_date.getTimezoneOffset() / 60;
|
||||
return -gmt_offset;
|
||||
};
|
||||
|
||||
var curDate = new Date();
|
||||
var months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
|
||||
var days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
|
||||
|
||||
|
||||
var timezoneDiff = this.serverGMToffset - getBrowserTimeZone();
|
||||
var timezoneTimeDiff = timezoneDiff*60*60*1000;
|
||||
|
||||
|
||||
selector.each(function () {
|
||||
try{
|
||||
var thisValue = $(this).html();
|
||||
// Split value into date and time
|
||||
var thisValueArray = thisValue.split(" ");
|
||||
var thisValueDate = thisValueArray[0];
|
||||
var thisValueTime = thisValueArray[1];
|
||||
|
||||
// Split date into components
|
||||
var thisValueDateArray = thisValueDate.split("-");
|
||||
var curYear = thisValueDateArray[0];
|
||||
var curMonth = thisValueDateArray[1]-1;
|
||||
var curDay = thisValueDateArray[2];
|
||||
|
||||
// Split time into components
|
||||
var thisValueTimeArray = thisValueTime.split(":");
|
||||
var curHour = thisValueTimeArray[0];
|
||||
var curMin = thisValueTimeArray[1];
|
||||
var curSec = thisValueTimeArray[2];
|
||||
|
||||
// Create this date
|
||||
var thisDate = new Date(curYear, curMonth, curDay, curHour, curMin, curSec);
|
||||
var thisTime = thisDate.getTime();
|
||||
var tzDate = new Date(thisTime - timezoneTimeDiff);
|
||||
//var tzDay = tzDate.getDay();//getDay will return the day of the week not the month
|
||||
//var tzDay = tzDate.getUTCDate(); //getUTCDate will return the day of the month
|
||||
var tzDay = tzDate.toString('d'); //
|
||||
var tzYear = tzDate.getFullYear();
|
||||
var tzHour = tzDate.getHours();
|
||||
var tzMin = tzDate.getMinutes();
|
||||
|
||||
// Create the full date
|
||||
//var fullDate = days[tzDate.getDay()] + ", " + months[tzDate.getMonth()] + " " + tzDay + ", " + tzYear + getAmPmTime(tzHour, tzMin);
|
||||
var fullDate = days[tzDate.getDay()] + ", " + months[tzDate.getMonth()] + " " + tzDay + ", " + tzYear + getAmPmTime(tzHour, tzMin);
|
||||
|
||||
// Get the time different
|
||||
var timeDiff = (curDate.getTime() - tzDate.getTime())/1000;
|
||||
var minDiff = Math.abs(timeDiff/60);
|
||||
var hourDiff = Math.abs(timeDiff/(60*60));
|
||||
var dayDiff = Math.abs(timeDiff/(60*60*24));
|
||||
var yearDiff = Math.abs(timeDiff/(60*60*24*365));
|
||||
|
||||
// If more than a day old, display the month, day and time (and year, if applicable)
|
||||
var fbDate = '';
|
||||
if (dayDiff > 1) {
|
||||
//fbDate = curDay + " " + months[tzDate.getMonth()].substring(0,3);
|
||||
fbDate = tzDay + " " + months[tzDate.getMonth()].substring(0,3);
|
||||
// Add the year, if applicable
|
||||
if (yearDiff > 1) {
|
||||
fbDate = fbDate + " "+ curYear;
|
||||
}
|
||||
|
||||
// Add the time
|
||||
fbDate = fbDate + getAmPmTime(tzHour, tzMin);
|
||||
}
|
||||
// Less than a day old, and more than an hour old
|
||||
else if (hourDiff >= 1) {
|
||||
var roundedHour = Math.round(hourDiff);
|
||||
if (roundedHour == 1)
|
||||
fbDate = "about an hour ago";
|
||||
else
|
||||
fbDate = roundedHour + " hours ago";
|
||||
}
|
||||
// Less than an hour, and more than a minute
|
||||
else if (minDiff >= 1) {
|
||||
var roundedMin = Math.round(minDiff);
|
||||
if (roundedMin == 1)
|
||||
fbDate = "about a minute ago";
|
||||
else
|
||||
fbDate = roundedMin + " minutes ago";
|
||||
}
|
||||
// Less than a minute
|
||||
else if (minDiff < 1) {
|
||||
fbDate = "less than a minute ago";
|
||||
}
|
||||
|
||||
// Update this element
|
||||
$(this).html(fbDate);
|
||||
$(this).attr('title', fullDate);
|
||||
}catch(e){}
|
||||
});
|
||||
});
|
||||
26
src/app/config.sample.php
Normal file
26
src/app/config.sample.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
ini_set('error_log', '_LOG_');
|
||||
|
||||
define('APP_NAME', 'Ice Framework');
|
||||
define('FB_URL', 'Ice Framework');
|
||||
define('TWITTER_URL', 'Ice Framework');
|
||||
|
||||
define('CLIENT_NAME', '_CLIENT_');
|
||||
define('APP_BASE_PATH', '_APP_BASE_PATH_');
|
||||
define('CLIENT_BASE_PATH', '_CLIENT_BASE_PATH_');
|
||||
define('BASE_URL','_BASE_URL_');
|
||||
define('CLIENT_BASE_URL','_CLIENTBASE_URL_');
|
||||
|
||||
define('APP_DB', '_APP_DB_');
|
||||
define('APP_USERNAME', '_APP_USERNAME_');
|
||||
define('APP_PASSWORD', '_APP_PASSWORD_');
|
||||
define('APP_HOST', '_APP_HOST_');
|
||||
define('APP_CON_STR', 'mysql://'.APP_USERNAME.':'.APP_PASSWORD.'@'.APP_HOST.'/'.APP_DB);
|
||||
|
||||
//file upload
|
||||
define('FILE_TYPES', 'jpg,png,jpeg');
|
||||
define('MAX_FILE_SIZE_KB', 10 * 1024);
|
||||
|
||||
//Home Links
|
||||
define('HOME_LINK_ADMIN', CLIENT_BASE_URL."?g=admin&n=dashboard&m=admin_Admin");
|
||||
define('HOME_LINK_OTHERS', CLIENT_BASE_URL."?g=modules&n=dashboard&m=module_My_Account");
|
||||
3
src/app/data.php
Normal file
3
src/app/data.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
include ('config.php');
|
||||
include (APP_BASE_PATH.'data.php');
|
||||
1
src/app/data/placeholder.txt
Normal file
1
src/app/data/placeholder.txt
Normal file
@@ -0,0 +1 @@
|
||||
http://icehrm.com
|
||||
3
src/app/fileupload.php
Normal file
3
src/app/fileupload.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
include ('config.php');
|
||||
include (APP_BASE_PATH.'fileupload.php');
|
||||
3
src/app/fileupload_page.php
Normal file
3
src/app/fileupload_page.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
include ('config.php');
|
||||
include (APP_BASE_PATH.'fileupload_page.php');
|
||||
3
src/app/header.php
Normal file
3
src/app/header.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
include (APP_BASE_PATH.'header.php');
|
||||
22
src/app/index.php
Normal file
22
src/app/index.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
if(!file_exists('config.php')){
|
||||
header("Location:install/");
|
||||
exit();
|
||||
}
|
||||
include ('config.php');
|
||||
if(!isset($_REQUEST['g']) || !isset($_REQUEST['n'])){
|
||||
header("Location:".CLIENT_BASE_URL."login.php");
|
||||
exit();
|
||||
}
|
||||
$group = $_REQUEST['g'];
|
||||
$name= $_REQUEST['n'];
|
||||
|
||||
$groups = array('admin','modules');
|
||||
|
||||
if($group == 'admin' || $group == 'modules'){
|
||||
$name = str_replace("..","",$name);
|
||||
$name = str_replace("/","",$name);
|
||||
include APP_BASE_PATH.'/'.$group.'/'.$name.'/index.php';
|
||||
}else{
|
||||
exit();
|
||||
}
|
||||
1058
src/app/install/bootstrap/css/bootstrap-responsive.css
vendored
Normal file
1058
src/app/install/bootstrap/css/bootstrap-responsive.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
9
src/app/install/bootstrap/css/bootstrap-responsive.min.css
vendored
Normal file
9
src/app/install/bootstrap/css/bootstrap-responsive.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
5774
src/app/install/bootstrap/css/bootstrap.css
vendored
Normal file
5774
src/app/install/bootstrap/css/bootstrap.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
9
src/app/install/bootstrap/css/bootstrap.min.css
vendored
Normal file
9
src/app/install/bootstrap/css/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
src/app/install/bootstrap/img/glyphicons-halflings-white.png
Normal file
BIN
src/app/install/bootstrap/img/glyphicons-halflings-white.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.6 KiB |
BIN
src/app/install/bootstrap/img/glyphicons-halflings.png
Normal file
BIN
src/app/install/bootstrap/img/glyphicons-halflings.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
2027
src/app/install/bootstrap/js/bootstrap.js
vendored
Normal file
2027
src/app/install/bootstrap/js/bootstrap.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
6
src/app/install/bootstrap/js/bootstrap.min.js
vendored
Normal file
6
src/app/install/bootstrap/js/bootstrap.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
8
src/app/install/config.php
Normal file
8
src/app/install/config.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
error_reporting(E_ERROR);
|
||||
ini_set("error_log", "/tmp/icehrm_install.log");
|
||||
define('CURRENT_PATH',dirname(__FILE__));
|
||||
define('CLIENT_APP_PATH',realpath(dirname(__FILE__)."/..")."/");
|
||||
define('APP_PATH',realpath(dirname(__FILE__)."/../..")."/");
|
||||
define('APP_NAME',"Ice Framework");
|
||||
define('APP_ID',"ice_framework");
|
||||
256
src/app/install/index.php
Normal file
256
src/app/install/index.php
Normal file
@@ -0,0 +1,256 @@
|
||||
<?php
|
||||
require dirname(__FILE__)."/config.php";
|
||||
$isConfigFileExists = file_exists(CLIENT_APP_PATH."config.php");
|
||||
|
||||
$errorMap = array();
|
||||
|
||||
if($isConfigFileExists){
|
||||
$data = file_get_contents(CLIENT_APP_PATH."config.php");
|
||||
if($data != ""){
|
||||
$errorMap[] = array("important","A configuration file exists","Application is already installed. If you want to reinstall, please delete the config file, clear data folder and use a new database during the installation.");
|
||||
}
|
||||
}else{
|
||||
$file = fopen(CLIENT_APP_PATH."config.php","w");
|
||||
fwrite($file,"");
|
||||
fclose($file);
|
||||
}
|
||||
|
||||
$isConfigFileWriteable = is_writable(CLIENT_APP_PATH."config.php");
|
||||
error_log("Config writable ".$isConfigFileWriteable);
|
||||
error_log("Config exists ".file_exists(CLIENT_APP_PATH."config.php"));
|
||||
if(!$isConfigFileWriteable){
|
||||
$errorMap[] = array("important","Configuration file [".CLIENT_APP_PATH."config.php] is not writable","Make this file writable",array("sudo touch ".CLIENT_APP_PATH."config.php","sudo chmod 777 ".CLIENT_APP_PATH."config.php"));
|
||||
}
|
||||
|
||||
$isConfigSampleFileExists = file_exists(CLIENT_APP_PATH."config.sample.php");
|
||||
|
||||
if(!$isConfigSampleFileExists){
|
||||
$errorMap[] = array("important","Sample configuration file doesn't exists","Please check :".CLIENT_APP_PATH."config.sample.php");
|
||||
}
|
||||
|
||||
$isDataFolderExists = is_dir(CLIENT_APP_PATH."data");
|
||||
$isDataFolderWritable = false;
|
||||
|
||||
|
||||
if(!$isDataFolderExists){
|
||||
$errorMap[] = array("important","Data directory does not exists","Please create directory :".CLIENT_APP_PATH."data",array("sudo mkdir ".CLIENT_APP_PATH."data"));
|
||||
}else{
|
||||
$file = fopen(CLIENT_APP_PATH."data/test.txt","w");
|
||||
if($file){
|
||||
fwrite($file,"Test file write");
|
||||
fclose($file);
|
||||
|
||||
$data = file_get_contents(CLIENT_APP_PATH."data/test.txt");
|
||||
|
||||
if($data == "Test file write"){
|
||||
$isDataFolderWritable = true;
|
||||
}
|
||||
unlink(CLIENT_APP_PATH."data/test.txt");
|
||||
}
|
||||
if(!$isDataFolderWritable){
|
||||
$errorMap[] = array("important","Data folder is not writable","Provide wirte permission to the web server user to ".CLIENT_APP_PATH."data",array("sudo chmod 777 ".CLIENT_APP_PATH."data"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
?><!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>IceHRM</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
|
||||
<!-- Le styles -->
|
||||
<link href="bootstrap/css/bootstrap.css" rel="stylesheet">
|
||||
|
||||
<script type="text/javascript" src="../../js/jquery.js"></script>
|
||||
<script src="bootstrap/js/bootstrap.js"></script>
|
||||
<link href="bootstrap/css/bootstrap-responsive.css" rel="stylesheet">
|
||||
<link href="styles.css?v=2" rel="stylesheet">
|
||||
|
||||
<script type="text/javascript" src="../../js/date.js"></script>
|
||||
<script type="text/javascript" src="../../js/json2.js"></script>
|
||||
<script type="text/javascript" src="../../js/CrockfordInheritance.v0.1.js"></script>
|
||||
|
||||
<!-- Le fav and touch icons -->
|
||||
<link rel="shortcut icon" href="bootstrap/ico/favicon.ico">
|
||||
<!-- IE Fix for HTML5 Tags -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
$(document).ready(function() {
|
||||
var url = top.location.href;
|
||||
|
||||
url = url.substring(0,url.lastIndexOf('/app'));
|
||||
$("#BASE_URL").val(url);
|
||||
});
|
||||
|
||||
function testDB(){
|
||||
var request = {};
|
||||
request["APP_DB"] = $("#APP_DB").val();
|
||||
request["APP_USERNAME"] = $("#APP_USERNAME").val();
|
||||
request["APP_PASSWORD"] = $("#APP_PASSWORD").val();
|
||||
request["APP_HOST"] = $("#APP_HOST").val();
|
||||
request["action"] = "TEST_DB";
|
||||
|
||||
$.post("submit.php",request , function(data) {
|
||||
if(data.status == "SUCCESS"){
|
||||
alert(data.msg);
|
||||
$("#installBtn").removeAttr('disabled');
|
||||
}else{
|
||||
alert(data.msg);
|
||||
}
|
||||
},"json");
|
||||
}
|
||||
|
||||
function install(){
|
||||
var request = {};
|
||||
request["APP_DB"] = $("#APP_DB").val();
|
||||
request["APP_USERNAME"] = $("#APP_USERNAME").val();
|
||||
request["APP_PASSWORD"] = $("#APP_PASSWORD").val();
|
||||
request["APP_HOST"] = $("#APP_HOST").val();
|
||||
request["action"] = "INS";
|
||||
|
||||
request["LOG"] = $("#LOG").val();
|
||||
request["BASE_URL"] = $("#BASE_URL").val();
|
||||
|
||||
if(request["BASE_URL"] == undefined || request["BASE_URL"] == null
|
||||
|| request["BASE_URL"] == ""){
|
||||
alert("Invalid Base URL");
|
||||
return;
|
||||
}
|
||||
|
||||
if(request["BASE_URL"].indexOf("http://") == 0 || request["BASE_URL"].indexOf("https://")){
|
||||
}else{
|
||||
alert("Invalid Base URL");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!endsWith(request["BASE_URL"],"/")){
|
||||
request["BASE_URL"] = request["BASE_URL"] + "/";
|
||||
}
|
||||
$("#installBtn").attr('disabled','disabled');
|
||||
$.post("submit.php",request , function(data) {
|
||||
if(data.status == "SUCCESS"){
|
||||
alert(data.msg);
|
||||
top.location.href = request["BASE_URL"]+"app/";
|
||||
}else{
|
||||
alert(data.msg);
|
||||
$("#installBtn").removeAttr('disabled');
|
||||
}
|
||||
},"json");
|
||||
}
|
||||
|
||||
function endsWith(str,pattern) {
|
||||
var d = str.length - pattern.length;
|
||||
return d >= 0 && str.lastIndexOf(pattern) === d;
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<div class="container-fluid bgbody" style="max-width:800px;padding-top:10px;margin:auto">
|
||||
<h1>IceHRM Installation</h1>
|
||||
<p class="p1">
|
||||
Please do not install this application if you have already installed (this could currupt existing instalation)
|
||||
</p>
|
||||
<?php if(count($errorMap)>0){?>
|
||||
<?php foreach($errorMap as $error){?>
|
||||
<p class="p2">
|
||||
<!--
|
||||
<span style="" class="label label-<?=$error[0]?>"><?=$error[1]?></span><br/>
|
||||
-->
|
||||
<span style="font-size:14px;color:red;font-weight: bold;"><?=$error[1]?></span><br/>
|
||||
<?=$error[2]?><br/>
|
||||
<?php if(!empty($error[3]) && is_array($error[3])){?>
|
||||
|
||||
<?php foreach($error[3] as $command){?>
|
||||
<span class="label label-inverse">
|
||||
<?=$command?></span><br/>
|
||||
<?php }?>
|
||||
|
||||
<?php }?>
|
||||
</p>
|
||||
<hr/>
|
||||
<?php }?>
|
||||
Once above errors are corrected, please reload the page<br/><br/>
|
||||
<button onclick="location.reload();;return false;" class="btn">Reload</button>
|
||||
<?php }else{?>
|
||||
<form class="form-horizontal" id="install_step1">
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<span class="label label-warning" id="install_step1_error" style="display:none;"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="LOG">Log file path</label>
|
||||
<div class="controls">
|
||||
<input class="input-xxlarge" type="text" id="LOG" name="LOG" value="data/icehrm.log"/>
|
||||
<span class="help-inline p1">Keep this empty if you want logs to be in web server's default logs</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="BASE_URL">App Url</label>
|
||||
<div class="controls">
|
||||
<input class="input-xxlarge" type="text" id="BASE_URL" name="BASE_URL" value=""/>
|
||||
<span class="help-inline p1">This is the web path to folder that you copy icehrm sources (e.g http://yourdomain.com/icehrm/)</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="APP_DB">MySql Database Name</label>
|
||||
<div class="controls">
|
||||
<input class="input-xxlarge" type="text" id="APP_DB" name="APP_DB" value="icehrmdb"/>
|
||||
<span class="help-inline p1">Application DB Name</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="APP_USERNAME">Database User</label>
|
||||
<div class="controls">
|
||||
<input class="input-xxlarge" type="text" id="APP_USERNAME" name="APP_USERNAME" value="icehrmuser"/>
|
||||
<span class="help-inline p1">Database username</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="APP_PASSWORD">Database User Password</label>
|
||||
<div class="controls">
|
||||
<input class="input-xxlarge" type="password" id="APP_PASSWORD" name="APP_PASSWORD" value=""/>
|
||||
<span class="help-inline p1">Database user's password</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="APP_HOST">Database Host</label>
|
||||
<div class="controls">
|
||||
<input class="input-xxlarge" type="text" id="APP_HOST" name="APP_HOST" value="localhost"/>
|
||||
<span class="help-inline p1">MySql DB Host</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<button id="testBtn" onclick="testDB();return false;" class="btn">Test Database Connectivity</button>
|
||||
<button id="installBtn" onclick="install();return false;" class="btn" disabled="disabled">Install Application</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<?php }?>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row-fluid" style="height:10px;">
|
||||
<div class="span12" style="padding:5px;">
|
||||
<p style="text-align:center;font-size: 10px;">
|
||||
<?=APP_NAME?> All rights reserved.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
9
src/app/install/styles.css
Normal file
9
src/app/install/styles.css
Normal file
@@ -0,0 +1,9 @@
|
||||
@CHARSET "ISO-8859-1";
|
||||
|
||||
.p1{
|
||||
font-size:11px;
|
||||
}
|
||||
|
||||
.p2{
|
||||
font-size:12px;
|
||||
}
|
||||
137
src/app/install/submit.php
Normal file
137
src/app/install/submit.php
Normal file
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
include dirname(__FILE__).'/config.php';
|
||||
include(CLIENT_APP_PATH.'../adodb512/adodb.inc.php');
|
||||
|
||||
$isConfigFileExists = file_exists(CLIENT_APP_PATH."config.php");
|
||||
$configData = file_get_contents(CLIENT_APP_PATH."config.php");
|
||||
|
||||
error_log("isConfigFileExists $isConfigFileExists");
|
||||
error_log("configData $configData");
|
||||
|
||||
$ret = array();
|
||||
|
||||
if(!$isConfigFileExists || $configData != ""){
|
||||
$ret["status"] = "ERROR";
|
||||
$ret["msg"] = "You are trying to install icehrm on an existing installation.";
|
||||
echo json_encode($ret);
|
||||
exit();
|
||||
}
|
||||
|
||||
$action = $_REQUEST['action'];
|
||||
|
||||
if($action == "TEST_DB"){
|
||||
|
||||
$db = NewADOConnection('mysql');
|
||||
$res = $db->Connect($_REQUEST["APP_HOST"], $_REQUEST["APP_USERNAME"], $_REQUEST["APP_PASSWORD"], $_REQUEST["APP_DB"]);
|
||||
|
||||
if (!$res){
|
||||
error_log('Could not connect: ' . mysql_error());
|
||||
$ret["status"] = "ERROR";
|
||||
$ret["msg"] = "Incorrect credentials or incorrect DB host";
|
||||
echo json_encode($ret);
|
||||
exit();
|
||||
}
|
||||
|
||||
$result = $db->Execute("Show tables");
|
||||
error_log(print_r("Number of tables:".$result->RecordCount(),true));
|
||||
$num_rows = $result->RecordCount();
|
||||
if($num_rows != 0){
|
||||
error_log('Database is not empty: ' . mysql_error());
|
||||
$ret["status"] = "ERROR";
|
||||
$ret["msg"] = "Database is not empty";
|
||||
echo json_encode($ret);
|
||||
exit();
|
||||
}
|
||||
|
||||
$ret["status"] = "SUCCESS";
|
||||
$ret["msg"] = "Successfully connected to the database";
|
||||
echo json_encode($ret);
|
||||
|
||||
}else if($action == "INS"){
|
||||
|
||||
$config = file_get_contents(CLIENT_APP_PATH."config.sample.php");
|
||||
|
||||
if(empty($config)){
|
||||
error_log('Sample config file is empty');
|
||||
$ret["status"] = "ERROR";
|
||||
$ret["msg"] = "Sample config file not found";
|
||||
echo json_encode($ret);
|
||||
exit();
|
||||
}
|
||||
|
||||
$config = str_replace("_LOG_", $_REQUEST['LOG'], $config);
|
||||
$config = str_replace("_APP_BASE_PATH_", APP_PATH, $config);
|
||||
$config = str_replace("_CLIENT_BASE_PATH_", CLIENT_APP_PATH, $config);
|
||||
$config = str_replace("_BASE_URL_", $_REQUEST['BASE_URL'], $config);
|
||||
$config = str_replace("_CLIENTBASE_URL_", $_REQUEST['BASE_URL']."app/", $config);
|
||||
$config = str_replace("_APP_DB_", $_REQUEST['APP_DB'], $config);
|
||||
$config = str_replace("_APP_USERNAME_", $_REQUEST['APP_USERNAME'], $config);
|
||||
$config = str_replace("_APP_PASSWORD_", $_REQUEST['APP_PASSWORD'], $config);
|
||||
$config = str_replace("_APP_HOST_", $_REQUEST['APP_HOST'], $config);
|
||||
$config = str_replace("_CLIENT_", 'app', $config);
|
||||
|
||||
$con = mysql_connect($_REQUEST["APP_HOST"],$_REQUEST["APP_USERNAME"],$_REQUEST["APP_PASSWORD"]);
|
||||
|
||||
$db = NewADOConnection('mysql');
|
||||
$res = $db->Connect($_REQUEST["APP_HOST"], $_REQUEST["APP_USERNAME"], $_REQUEST["APP_PASSWORD"], $_REQUEST["APP_DB"]);
|
||||
|
||||
|
||||
if (!$res){
|
||||
error_log('Could not connect: ' . mysql_error());
|
||||
$ret["status"] = "ERROR";
|
||||
$ret["msg"] = "Incorrect credentials or incorrect DB host";
|
||||
echo json_encode($ret);
|
||||
exit();
|
||||
}
|
||||
|
||||
$result = $db->Execute("Show tables");
|
||||
error_log(print_r("Number of tables:".$result->RecordCount(),true));
|
||||
$num_rows = $result->RecordCount();
|
||||
if($num_rows != 0){
|
||||
error_log('Database is not empty: ' . mysql_error());
|
||||
$ret["status"] = "ERROR";
|
||||
$ret["msg"] = "Database is not empty";
|
||||
echo json_encode($ret);
|
||||
exit();
|
||||
}
|
||||
|
||||
|
||||
//Run create table script
|
||||
$insql = file_get_contents(CLIENT_APP_PATH."../scripts/".APP_ID."db.sql");
|
||||
$sql_list = preg_split('/;/',$insql);
|
||||
foreach($sql_list as $sql){
|
||||
if (preg_match('/^\s+$/', $sql) || $sql == '') { # skip empty lines
|
||||
continue;
|
||||
}
|
||||
$db->Execute($sql);
|
||||
}
|
||||
|
||||
//Run create table script
|
||||
$insql = file_get_contents(CLIENT_APP_PATH."../scripts/".APP_ID."_master_data.sql");
|
||||
$sql_list = preg_split('/;/',$insql);
|
||||
foreach($sql_list as $sql){
|
||||
if (preg_match('/^\s+$/', $sql) || $sql == '') { # skip empty lines
|
||||
continue;
|
||||
}
|
||||
$db->Execute($sql);
|
||||
}
|
||||
|
||||
|
||||
//Write config file
|
||||
|
||||
$file = fopen(CLIENT_APP_PATH."config.php","w");
|
||||
if($file){
|
||||
fwrite($file,$config);
|
||||
fclose($file);
|
||||
}else{
|
||||
error_log('Unable to write configurations to file');
|
||||
$ret["status"] = "ERROR";
|
||||
$ret["msg"] = "Unable to write configurations to file";
|
||||
echo json_encode($ret);
|
||||
exit();
|
||||
}
|
||||
|
||||
$ret["status"] = "SUCCESS";
|
||||
$ret["msg"] = "Successfully installed. Please rename or delete install folder";
|
||||
echo json_encode($ret);
|
||||
}
|
||||
3
src/app/login.php
Normal file
3
src/app/login.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
include ('config.php');
|
||||
include (APP_BASE_PATH.'login.php');
|
||||
3
src/app/logout.php
Normal file
3
src/app/logout.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
include ('config.php');
|
||||
include (APP_BASE_PATH.'logout.php');
|
||||
3
src/app/rest.php
Normal file
3
src/app/rest.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
include ('config.php');
|
||||
include (APP_BASE_PATH.'rest.php');
|
||||
3
src/app/service.php
Normal file
3
src/app/service.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
include ('config.php');
|
||||
include (APP_BASE_PATH.'service.php');
|
||||
1058
src/bootstrap/css/bootstrap-responsive.css
vendored
Normal file
1058
src/bootstrap/css/bootstrap-responsive.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
9
src/bootstrap/css/bootstrap-responsive.min.css
vendored
Normal file
9
src/bootstrap/css/bootstrap-responsive.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
5774
src/bootstrap/css/bootstrap.css
vendored
Normal file
5774
src/bootstrap/css/bootstrap.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
9
src/bootstrap/css/bootstrap.min.css
vendored
Normal file
9
src/bootstrap/css/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
src/bootstrap/img/glyphicons-halflings-white.png
Normal file
BIN
src/bootstrap/img/glyphicons-halflings-white.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.6 KiB |
BIN
src/bootstrap/img/glyphicons-halflings.png
Normal file
BIN
src/bootstrap/img/glyphicons-halflings.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
2027
src/bootstrap/js/bootstrap.js
vendored
Normal file
2027
src/bootstrap/js/bootstrap.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
6
src/bootstrap/js/bootstrap.min.js
vendored
Normal file
6
src/bootstrap/js/bootstrap.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
35
src/classes/AbstractInitialize.php
Normal file
35
src/classes/AbstractInitialize.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/*
|
||||
This file is part of Ice Framework.
|
||||
|
||||
Ice Framework is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Ice Framework is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Ice Framework. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
------------------------------------------------------------------
|
||||
|
||||
Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd]
|
||||
Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah)
|
||||
*/
|
||||
|
||||
abstract class AbstractInitialize{
|
||||
var $baseService = null;
|
||||
public function setBaseService($baseService){
|
||||
$this->baseService = $baseService;
|
||||
}
|
||||
|
||||
public function getCurrentProfileId(){
|
||||
return $this->baseService->getCurrentProfileId();
|
||||
}
|
||||
|
||||
public abstract function init();
|
||||
}
|
||||
115
src/classes/AbstractModuleManager.php
Normal file
115
src/classes/AbstractModuleManager.php
Normal file
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
/**
|
||||
*The base class for module manager classes. ModuleManager classes which extend this class provide core backend functionality
|
||||
*to each module such as defining models, error handliing and other configuration details
|
||||
*@class AbstractModuleManager
|
||||
*/
|
||||
abstract class AbstractModuleManager{
|
||||
|
||||
private $fileFieldMappings = array();
|
||||
private $userClasses = array();
|
||||
private $errorMappings = array();
|
||||
private $modelClasses = array();
|
||||
|
||||
/**
|
||||
* Override this method in module manager class to define user classes.
|
||||
* A user class is a class that is mapped to a table having a field named profile. The profile field is mapped to the id of a Profile element.
|
||||
* When a user is saving this type of an object in db, profile field will be set to the id of the Profile of currently logged in or switched user.
|
||||
* When a user is retriving this type of records, only the records having profile field set to currently logged in users profile id will be released.
|
||||
* @method initializeUserClasses
|
||||
* @example
|
||||
public function initializeUserClasses(){
|
||||
$this->addUserClass("EmployeeDocument");
|
||||
}
|
||||
*
|
||||
*/
|
||||
public abstract function initializeUserClasses();
|
||||
|
||||
/**
|
||||
* Override this method in module manager class to define file field mappings. If you have a table field that stores a name of a file which need to be
|
||||
* deleted from the disk when the record is deleted a file field mapping should be added.
|
||||
* @method initializeFieldMappings
|
||||
* @example
|
||||
public function initializeFieldMappings(){
|
||||
$this->addFileFieldMapping('EmployeeDocument', 'attachment', 'name');
|
||||
}
|
||||
*/
|
||||
public abstract function initializeFieldMappings();
|
||||
|
||||
|
||||
/**
|
||||
* Override this method in module manager class to define DB error mappings. Some actions to your model classes trigger database errors.
|
||||
* These errors need to be translated to user friendly texts using DB error mappings
|
||||
* @method initializeDatabaseErrorMappings
|
||||
* @example
|
||||
public function initializeDatabaseErrorMappings(){
|
||||
$this->addDatabaseErrorMapping('CONSTRAINT `Fk_User_Employee` FOREIGN KEY',"Can not delete Employee, please delete the User for this employee first.");
|
||||
$this->addDatabaseErrorMapping("Duplicate entry|for key 'employee'","A duplicate entry found");
|
||||
}
|
||||
*/
|
||||
public abstract function initializeDatabaseErrorMappings();
|
||||
|
||||
/**
|
||||
* Override this method in module manager class to add model classes to this module. All the model classes defind for the module should be added here
|
||||
* @method setupModuleClassDefinitions
|
||||
* @example
|
||||
public function setupModuleClassDefinitions(){
|
||||
$this->addModelClass('Employee');
|
||||
$this->addModelClass('EmploymentStatus');
|
||||
}
|
||||
*/
|
||||
public abstract function setupModuleClassDefinitions();
|
||||
|
||||
|
||||
public function setupRestEndPoints(){
|
||||
|
||||
}
|
||||
|
||||
public function setupFileFieldMappings(&$fileFields){
|
||||
foreach ($this->fileFieldMappings as $mapping){
|
||||
if(empty($fileFields[$mapping[0]])){
|
||||
$fileFields[$mapping[0]] = array();
|
||||
}
|
||||
|
||||
$fileFields[$mapping[0]][$mapping[1]] = $mapping[2];
|
||||
}
|
||||
}
|
||||
|
||||
public function setupUserClasses(&$userTables){
|
||||
foreach($this->userClasses as $className){
|
||||
if(!in_array($className, $userTables)){
|
||||
$userTables[] = $className;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function setupErrorMappings(&$mysqlErrors){
|
||||
foreach($this->errorMappings as $name=>$desc){
|
||||
$mysqlErrors[$name] = $desc;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function getModelClasses(){
|
||||
return $this->modelClasses;
|
||||
}
|
||||
|
||||
protected function addFileFieldMapping($className, $fieldName, $fileTableFieldName){
|
||||
$this->fileFieldMappings[] = array($className, $fieldName, $fileTableFieldName);
|
||||
}
|
||||
|
||||
protected function addUserClass($className){
|
||||
$this->userClasses[] = $className;
|
||||
}
|
||||
|
||||
protected function addDatabaseErrorMapping($error, $description){
|
||||
$this->errorMappings[$error] = $description;
|
||||
}
|
||||
|
||||
protected function addModelClass($className){
|
||||
$this->modelClasses[] = $className;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
1119
src/classes/BaseService.php
Normal file
1119
src/classes/BaseService.php
Normal file
File diff suppressed because it is too large
Load Diff
33
src/classes/CronUtils.php
Normal file
33
src/classes/CronUtils.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
class CronUtils{
|
||||
var $clientBasePath;
|
||||
var $cronFile;
|
||||
|
||||
private static $me = null;
|
||||
|
||||
private function __construct($clientBasePath, $cronFile){
|
||||
$this->clientBasePath = $clientBasePath;
|
||||
$this->cronFile = $cronFile;
|
||||
}
|
||||
|
||||
public static function getInstance($clientBasePath, $cronFile){
|
||||
if(empty(self::$me)){
|
||||
self::$me = new CronUtils($clientBasePath, $cronFile);
|
||||
}
|
||||
return self::$me;
|
||||
}
|
||||
|
||||
|
||||
public function run(){
|
||||
$ams = scandir($this->clientBasePath);
|
||||
|
||||
foreach($ams as $am){
|
||||
if(is_dir($this->clientBasePath.$am) && $am != '.' && $am != '..'){
|
||||
$command = "php ".$this->cronFile." -c".$this->clientBasePath.$am;
|
||||
echo "Run:".$command."\r\n";
|
||||
passthru($command, $res);
|
||||
echo "Result :".$res."\r\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
260
src/classes/EmailSender.php
Normal file
260
src/classes/EmailSender.php
Normal file
@@ -0,0 +1,260 @@
|
||||
<?php
|
||||
/*
|
||||
* This file is part of Ice Framework.
|
||||
* Copyright Thilina Hasantha (thilina.hasantha[at]gmail.com | http://facebook.com/thilinah | https://twitter.com/thilina84)
|
||||
* Licensed under MIT (https://github.com/thilinah/ice-framework/master/LICENSE)
|
||||
*/
|
||||
|
||||
use Aws\Ses\SesClient;
|
||||
|
||||
abstract class EmailSender{
|
||||
var $settings = null;
|
||||
public function __construct($settings){
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
public function sendEmail($subject, $toEmail, $template, $params, $ccList = array(), $bccList = array()){
|
||||
|
||||
$body = $template;
|
||||
|
||||
foreach($params as $k=>$v){
|
||||
$body = str_replace("#_".$k."_#", $v, $body);
|
||||
}
|
||||
|
||||
$fromEmail = APP_NAME." <".$this->settings->getSetting("Email: Email From").">";
|
||||
|
||||
|
||||
//Convert to an html email
|
||||
$emailBody = file_get_contents(APP_BASE_PATH.'/templates/email/emailBody.html');
|
||||
|
||||
$emailBody = str_replace("#_emailBody_#", $body, $emailBody);
|
||||
$emailBody = str_replace("#_logourl_#",
|
||||
BASE_URL."images/logo.png"
|
||||
, $emailBody);
|
||||
|
||||
$user = new User();
|
||||
$user->load("username = ?",array('admin'));
|
||||
|
||||
if(empty($user->id)){
|
||||
$users = $user->Find("user_level = ?",array('Admin'));
|
||||
$user = $users[0];
|
||||
}
|
||||
|
||||
$emailBody = str_replace("#_adminEmail_#", $user->email, $emailBody);
|
||||
$emailBody = str_replace("#_url_#", CLIENT_BASE_URL, $emailBody);
|
||||
foreach($params as $k=>$v){
|
||||
$emailBody = str_replace("#_".$k."_#", $v, $emailBody);
|
||||
}
|
||||
|
||||
$this->sendMail($subject, $emailBody, $toEmail, $fromEmail, $user->email, $ccList, $bccList);
|
||||
}
|
||||
|
||||
public function sendEmailWithoutWrap($subject, $toEmail, $template, $params, $ccList = array(), $bccList = array()){
|
||||
|
||||
$body = $template;
|
||||
|
||||
foreach($params as $k=>$v){
|
||||
$body = str_replace("#_".$k."_#", $v, $body);
|
||||
}
|
||||
|
||||
$fromEmail = APP_NAME." <".$this->settings->getSetting("Email: Email From").">";
|
||||
|
||||
|
||||
//Convert to an html email
|
||||
$emailBody = $body;
|
||||
$emailBody = str_replace("#_logourl_#",
|
||||
BASE_URL."images/logo.png"
|
||||
, $emailBody);
|
||||
|
||||
$user = new User();
|
||||
$user->load("username = ?",array('admin'));
|
||||
|
||||
if(empty($user->id)){
|
||||
$users = $user->Find("user_level = ?",array('Admin'));
|
||||
$user = $users[0];
|
||||
}
|
||||
|
||||
$emailBody = str_replace("#_adminEmail_#", $user->email, $emailBody);
|
||||
$emailBody = str_replace("#_url_#", CLIENT_BASE_URL, $emailBody);
|
||||
foreach($params as $k=>$v){
|
||||
$emailBody = str_replace("#_".$k."_#", $v, $emailBody);
|
||||
}
|
||||
|
||||
$this->sendMail($subject, $emailBody, $toEmail, $fromEmail, $user->email, $ccList, $bccList);
|
||||
}
|
||||
|
||||
protected abstract function sendMail($subject, $body, $toEmail, $fromEmail, $replyToEmail = null, $ccList = array(), $bccList = array());
|
||||
|
||||
public function sendResetPasswordEmail($emailOrUserId){
|
||||
$user = new User();
|
||||
$user->Load("email = ?",array($emailOrUserId));
|
||||
if(empty($user->id)){
|
||||
$user = new User();
|
||||
$user->Load("username = ?",array($emailOrUserId));
|
||||
if(empty($user->id)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$params = array();
|
||||
//$params['user'] = $user->first_name." ".$user->last_name;
|
||||
$params['url'] = CLIENT_BASE_URL;
|
||||
|
||||
$newPassHash = array();
|
||||
$newPassHash["CLIENT_NAME"] = CLIENT_NAME;
|
||||
$newPassHash["oldpass"] = $user->password;
|
||||
$newPassHash["email"] = $user->email;
|
||||
$newPassHash["time"] = time();
|
||||
$json = json_encode($newPassHash);
|
||||
|
||||
$encJson = AesCtr::encrypt($json, $user->password, 256);
|
||||
$encJson = urlencode($user->id."-".$encJson);
|
||||
$params['passurl'] = CLIENT_BASE_URL."service.php?a=rsp&key=".$encJson;
|
||||
|
||||
$emailBody = file_get_contents(APP_BASE_PATH.'/templates/email/passwordReset.html');
|
||||
|
||||
$this->sendEmail("[".APP_NAME."] Password Change Request", $user->email, $emailBody, $params);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class SNSEmailSender extends EmailSender{
|
||||
var $ses = null;
|
||||
public function __construct($settings){
|
||||
parent::__construct($settings);
|
||||
$arr = array(
|
||||
'key' => $this->settings->getSetting('Email: Amazon Access Key ID'),
|
||||
'secret' => $this->settings->getSetting('Email: Amazon Secret Access Key'),
|
||||
'region' => AWS_REGION
|
||||
);
|
||||
//$this->ses = new AmazonSES($arr);
|
||||
$this->ses = SesClient::factory($arr);
|
||||
}
|
||||
|
||||
protected function sendMail($subject, $body, $toEmail, $fromEmail, $replyToEmail = null, $ccList = array(), $bccList = array()) {
|
||||
|
||||
if(empty($replyToEmail)){
|
||||
$replyToEmail = $fromEmail;
|
||||
}
|
||||
|
||||
LogManager::getInstance()->info("Sending email to: ".$toEmail."/ from: ".$fromEmail);
|
||||
|
||||
$toArray = array('ToAddresses' => array($toEmail),
|
||||
'CcAddresses' => $ccList,
|
||||
'BccAddresses' => $bccList);
|
||||
$message = array(
|
||||
'Subject' => array(
|
||||
'Data' => $subject,
|
||||
'Charset' => 'UTF-8'
|
||||
),
|
||||
'Body' => array(
|
||||
'Html' => array(
|
||||
'Data' => $body,
|
||||
'Charset' => 'UTF-8'
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
//$response = $this->ses->sendEmail($fromEmail, $toArray, $message);
|
||||
$response = $this->ses->sendEmail(
|
||||
array(
|
||||
'Source'=>$fromEmail,
|
||||
'Destination'=>$toArray,
|
||||
'Message'=>$message,
|
||||
'ReplyToAddresses' => array($replyToEmail),
|
||||
'ReturnPath' => $fromEmail
|
||||
)
|
||||
);
|
||||
|
||||
LogManager::getInstance()->info("SES Response:".print_r($response,true));
|
||||
|
||||
return $response;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class SMTPEmailSender extends EmailSender{
|
||||
|
||||
public function __construct($settings){
|
||||
parent::__construct($settings);
|
||||
}
|
||||
|
||||
protected function sendMail($subject, $body, $toEmail, $fromEmail, $replyToEmail = null, $ccList = array(), $bccList = array()) {
|
||||
|
||||
if(empty($replyToEmail)){
|
||||
$replyToEmail = $fromEmail;
|
||||
}
|
||||
|
||||
LogManager::getInstance()->info("Sending email to: ".$toEmail."/ from: ".$fromEmail);
|
||||
|
||||
$host = $this->settings->getSetting("Email: SMTP Host");
|
||||
$username = $this->settings->getSetting("Email: SMTP User");
|
||||
$password = $this->settings->getSetting("Email: SMTP Password");
|
||||
$port = $this->settings->getSetting("Email: SMTP Port");
|
||||
|
||||
if(empty($port)){
|
||||
$port = '25';
|
||||
}
|
||||
|
||||
if($this->settings->getSetting("Email: SMTP Authentication Required") == "0"){
|
||||
$auth = array ('host' => $host,
|
||||
'auth' => false);
|
||||
}else{
|
||||
$auth = array ('host' => $host,
|
||||
'auth' => true,
|
||||
'username' => $username,
|
||||
'port' => $port,
|
||||
'password' => $password);
|
||||
}
|
||||
|
||||
|
||||
$smtp = Mail::factory('smtp',$auth);
|
||||
|
||||
$headers = array ('MIME-Version' => '1.0',
|
||||
'Content-type' => 'text/html',
|
||||
'charset' => 'iso-8859-1',
|
||||
'From' => $fromEmail,
|
||||
'To' => $toEmail,
|
||||
'Reply-To' => $replyToEmail,
|
||||
'Subject' => $subject);
|
||||
|
||||
|
||||
$mail = $smtp->send($toEmail, $headers, $body);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PHPMailer extends EmailSender{
|
||||
|
||||
public function __construct($settings){
|
||||
parent::__construct($settings);
|
||||
}
|
||||
|
||||
protected function sendMail($subject, $body, $toEmail, $fromEmail, $replyToEmail = null, $ccList = array(), $bccList = array()) {
|
||||
|
||||
if(empty($replyToEmail)){
|
||||
$replyToEmail = $fromEmail;
|
||||
}
|
||||
|
||||
LogManager::getInstance()->info("Sending email to: ".$toEmail."/ from: ".$fromEmail);
|
||||
|
||||
$headers = 'MIME-Version: 1.0' . "\r\n";
|
||||
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
|
||||
$headers .= 'From: '.$fromEmail. "\r\n";
|
||||
$headers .= 'ReplyTo: '.$replyToEmail. "\r\n";
|
||||
$headers .= 'Ice-Mailer: PHP/' . phpversion();
|
||||
|
||||
// Mail it
|
||||
$res = mail($toEmail, $subject, $body, $headers);
|
||||
|
||||
LogManager::getInstance()->info("PHP mailer result : ".$res);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
4
src/classes/ErrorCodes.php
Normal file
4
src/classes/ErrorCodes.php
Normal file
@@ -0,0 +1,4 @@
|
||||
<?php
|
||||
class ErrorCodes{
|
||||
|
||||
}
|
||||
307
src/classes/FileService.php
Normal file
307
src/classes/FileService.php
Normal file
@@ -0,0 +1,307 @@
|
||||
<?php
|
||||
/*
|
||||
This file is part of Ice Framework.
|
||||
|
||||
Ice Framework is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Ice Framework is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Ice Framework. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
------------------------------------------------------------------
|
||||
|
||||
Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd]
|
||||
Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah)
|
||||
*/
|
||||
|
||||
class FileService{
|
||||
|
||||
private static $me = null;
|
||||
|
||||
private $memcache;
|
||||
|
||||
private function __construct(){
|
||||
|
||||
}
|
||||
|
||||
public static function getInstance(){
|
||||
if(empty(self::$me)){
|
||||
self::$me = new FileService();
|
||||
}
|
||||
|
||||
return self::$me;
|
||||
}
|
||||
|
||||
public function getFromCache($key){
|
||||
try{
|
||||
if(empty($this->memcache)){
|
||||
$this->memcache = new Memcached();
|
||||
$this->memcache->addServer("127.0.0.1", 11211);
|
||||
}
|
||||
|
||||
$data = $this->memcache->get($key);
|
||||
if(!empty($data)){
|
||||
return $data;
|
||||
}
|
||||
|
||||
return null;
|
||||
}catch(Exception $e){
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function saveInCache($key, $data, $expire){
|
||||
try{
|
||||
if(empty($this->memcache)){
|
||||
$this->memcache = new Memcached();
|
||||
$this->memcache->addServer("127.0.0.1", 11211);
|
||||
}
|
||||
$this->memcache->set($key,$data, $expire);
|
||||
}catch(Exception $e){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public function checkAddSmallProfileImage($profileImage){
|
||||
$file = new File();
|
||||
$file->Load('name = ?',array($profileImage->name."_small"));
|
||||
|
||||
if(empty($file->id)){
|
||||
|
||||
LogManager::getInstance()->info("Small profile image ".$profileImage->name."_small not found");
|
||||
|
||||
$largeFileUrl = $this->getFileUrl($profileImage->name);
|
||||
|
||||
$file->name = $profileImage->name."_small";
|
||||
$signInMappingField = SIGN_IN_ELEMENT_MAPPING_FIELD_NAME;
|
||||
$file->$signInMappingField = $profileImage->$signInMappingField;
|
||||
$file->filename = $file->name.str_replace($profileImage->name,"",$profileImage->filename);
|
||||
$file->file_group = $profileImage->file_group;
|
||||
|
||||
file_put_contents("/tmp/".$file->filename."_orig", file_get_contents($largeFileUrl));
|
||||
|
||||
if(file_exists("/tmp/".$file->filename."_orig")){
|
||||
|
||||
//Resize image to 100
|
||||
|
||||
$img = new abeautifulsite\SimpleImage("/tmp/".$file->filename."_orig");
|
||||
$img->fit_to_width(100);
|
||||
$img->save("/tmp/".$file->filename);
|
||||
|
||||
|
||||
$uploadFilesToS3Key = SettingsManager::getInstance()->getSetting("Files: Amazon S3 Key for File Upload");
|
||||
$uploadFilesToS3Secret = SettingsManager::getInstance()->getSetting("Files: Amazone S3 Secret for File Upload");
|
||||
$s3Bucket = SettingsManager::getInstance()->getSetting("Files: S3 Bucket");
|
||||
|
||||
$uploadname = CLIENT_NAME."/".$file->filename;
|
||||
$localFile = "/tmp/".$file->filename;
|
||||
|
||||
$s3FileSys = new S3FileSystem($uploadFilesToS3Key, $uploadFilesToS3Secret);
|
||||
$result = $s3FileSys->putObject($s3Bucket, $uploadname, $localFile, 'authenticated-read');
|
||||
|
||||
unlink("/tmp/".$file->filename);
|
||||
unlink("/tmp/".$file->filename."_orig");
|
||||
|
||||
LogManager::getInstance()->info("Upload Result:".print_r($result,true));
|
||||
|
||||
if(!empty($result)){
|
||||
$ok = $file->Save();
|
||||
}
|
||||
|
||||
return $file;
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
public function updateSmallProfileImage($profile){
|
||||
$file = new File();
|
||||
$file->Load('name = ?',array('profile_image_'.$profile->id));
|
||||
|
||||
if($file->name == 'profile_image_'.$profile->id){
|
||||
|
||||
$uploadFilesToS3 = SettingsManager::getInstance()->getSetting("Files: Upload Files to S3");
|
||||
if($uploadFilesToS3 == "1"){
|
||||
|
||||
try{
|
||||
$fileNew = $this->checkAddSmallProfileImage($file);
|
||||
if(!empty($fileNew)){
|
||||
$file = $fileNew;
|
||||
}
|
||||
|
||||
$uploadFilesToS3Key = SettingsManager::getInstance()->getSetting("Files: Amazon S3 Key for File Upload");
|
||||
$uploadFilesToS3Secret = SettingsManager::getInstance()->getSetting("Files: Amazone S3 Secret for File Upload");
|
||||
$s3FileSys = new S3FileSystem($uploadFilesToS3Key, $uploadFilesToS3Secret);
|
||||
$s3WebUrl = SettingsManager::getInstance()->getSetting("Files: S3 Web Url");
|
||||
$fileUrl = $s3WebUrl.CLIENT_NAME."/".$file->filename;
|
||||
|
||||
$expireUrl = $this->getFromCache($fileUrl);
|
||||
if(empty($expireUrl)){
|
||||
$expireUrl = $s3FileSys->generateExpiringURL($fileUrl, 600);
|
||||
$this->saveInCache($fileUrl, $expireUrl, 500);
|
||||
}
|
||||
|
||||
|
||||
$profile->image = $expireUrl;
|
||||
|
||||
}catch (Exception $e){
|
||||
LogManager::getInstance()->error("Error generating profile image: ".$e->getMessage());
|
||||
if($profile->gender == 'Female'){
|
||||
$profile->image = BASE_URL."images/user_female.png";
|
||||
}else{
|
||||
$profile->image = BASE_URL."images/user_male.png";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}else{
|
||||
$profile->image = CLIENT_BASE_URL.'data/'.$file->filename;
|
||||
}
|
||||
|
||||
}else{
|
||||
if($profile->gender == 'Female'){
|
||||
$profile->image = BASE_URL."images/user_female.png";
|
||||
}else{
|
||||
$profile->image = BASE_URL."images/user_male.png";
|
||||
}
|
||||
}
|
||||
|
||||
return $profile;
|
||||
}
|
||||
|
||||
public function updateProfileImage($profile){
|
||||
$file = new File();
|
||||
$file->Load('name = ?',array('profile_image_'.$profile->id));
|
||||
|
||||
if($file->name == 'profile_image_'.$profile->id){
|
||||
$uploadFilesToS3 = SettingsManager::getInstance()->getSetting("Files: Upload Files to S3");
|
||||
if($uploadFilesToS3 == "1"){
|
||||
$uploadFilesToS3Key = SettingsManager::getInstance()->getSetting("Files: Amazon S3 Key for File Upload");
|
||||
$uploadFilesToS3Secret = SettingsManager::getInstance()->getSetting("Files: Amazone S3 Secret for File Upload");
|
||||
$s3FileSys = new S3FileSystem($uploadFilesToS3Key, $uploadFilesToS3Secret);
|
||||
$s3WebUrl = SettingsManager::getInstance()->getSetting("Files: S3 Web Url");
|
||||
$fileUrl = $s3WebUrl.CLIENT_NAME."/".$file->filename;
|
||||
|
||||
$expireUrl = $this->getFromCache($fileUrl);
|
||||
if(empty($expireUrl)){
|
||||
$expireUrl = $s3FileSys->generateExpiringURL($fileUrl, 600);
|
||||
$this->saveInCache($fileUrl, $expireUrl, 500);
|
||||
}
|
||||
|
||||
|
||||
$profile->image = $expireUrl;
|
||||
}else{
|
||||
$profile->image = CLIENT_BASE_URL.'data/'.$file->filename;
|
||||
}
|
||||
|
||||
}else{
|
||||
if($profile->gender == 'Female'){
|
||||
$profile->image = BASE_URL."images/user_female.png";
|
||||
}else{
|
||||
$profile->image = BASE_URL."images/user_male.png";
|
||||
}
|
||||
}
|
||||
|
||||
return $profile;
|
||||
}
|
||||
|
||||
public function getFileUrl($fileName){
|
||||
$file = new File();
|
||||
$file->Load('name = ?',array($fileName));
|
||||
|
||||
$uploadFilesToS3 = SettingsManager::getInstance()->getSetting("Files: Upload Files to S3");
|
||||
|
||||
if($uploadFilesToS3 == "1"){
|
||||
$uploadFilesToS3Key = SettingsManager::getInstance()->getSetting("Files: Amazon S3 Key for File Upload");
|
||||
$uploadFilesToS3Secret = SettingsManager::getInstance()->getSetting("Files: Amazone S3 Secret for File Upload");
|
||||
$s3FileSys = new S3FileSystem($uploadFilesToS3Key, $uploadFilesToS3Secret);
|
||||
$s3WebUrl = SettingsManager::getInstance()->getSetting("Files: S3 Web Url");
|
||||
$fileUrl = $s3WebUrl.CLIENT_NAME."/".$file->filename;
|
||||
|
||||
$expireUrl = $this->getFromCache($fileUrl);
|
||||
if(empty($expireUrl)){
|
||||
$expireUrl = $s3FileSys->generateExpiringURL($fileUrl, 600);
|
||||
$this->saveInCache($fileUrl, $expireUrl, 500);
|
||||
}
|
||||
|
||||
|
||||
return $expireUrl;
|
||||
}else{
|
||||
return CLIENT_BASE_URL.'data/'.$file->filename;
|
||||
}
|
||||
}
|
||||
|
||||
public function deleteProfileImage($profileId){
|
||||
$file = new File();
|
||||
$file->Load('name = ?',array('profile_image_'.$profileId));
|
||||
if($file->name == 'profile_image_'.$profileId){
|
||||
$ok = $file->Delete();
|
||||
if($ok){
|
||||
LogManager::getInstance()->info("Delete File:".CLIENT_BASE_PATH.$file->filename);
|
||||
unlink(CLIENT_BASE_PATH.'data/'.$file->filename);
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$file = new File();
|
||||
$file->Load('name = ?',array('profile_image_'.$profileId."_small"));
|
||||
if($file->name == 'profile_image_'.$profileId."_small"){
|
||||
$ok = $file->Delete();
|
||||
if($ok){
|
||||
LogManager::getInstance()->info("Delete File:".CLIENT_BASE_PATH.$file->filename);
|
||||
unlink(CLIENT_BASE_PATH.'data/'.$file->filename);
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function deleteFileByField($value, $field){
|
||||
LogManager::getInstance()->info("Delete file by field: $field / value: $value");
|
||||
$file = new File();
|
||||
$file->Load("$field = ?",array($value));
|
||||
if($file->$field == $value){
|
||||
$ok = $file->Delete();
|
||||
if($ok){
|
||||
$uploadFilesToS3 = SettingsManager::getInstance()->getSetting("Files: Upload Files to S3");
|
||||
|
||||
if($uploadFilesToS3 == "1"){
|
||||
$uploadFilesToS3Key = SettingsManager::getInstance()->getSetting("Files: Amazon S3 Key for File Upload");
|
||||
$uploadFilesToS3Secret = SettingsManager::getInstance()->getSetting("Files: Amazone S3 Secret for File Upload");
|
||||
$s3Bucket = SettingsManager::getInstance()->getSetting("Files: S3 Bucket");
|
||||
|
||||
$uploadname = CLIENT_NAME."/".$file->filename;
|
||||
LogManager::getInstance()->info("Delete from S3:".$uploadname);
|
||||
|
||||
$s3FileSys = new S3FileSystem($uploadFilesToS3Key, $uploadFilesToS3Secret);
|
||||
$res = $s3FileSys->deleteObject($s3Bucket, $uploadname);
|
||||
|
||||
}else{
|
||||
LogManager::getInstance()->info("Delete:".CLIENT_BASE_PATH.'data/'.$file->filename);
|
||||
unlink(CLIENT_BASE_PATH.'data/'.$file->filename);
|
||||
}
|
||||
|
||||
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
156
src/classes/ModuleBuilder.php
Normal file
156
src/classes/ModuleBuilder.php
Normal file
@@ -0,0 +1,156 @@
|
||||
<?php
|
||||
|
||||
class ModuleBuilder {
|
||||
var $modules = array();
|
||||
|
||||
public function addModuleOrGroup($module){
|
||||
$this->modules[] = $module;
|
||||
}
|
||||
|
||||
public function getTabHeadersHTML(){
|
||||
$html = "";
|
||||
foreach($this->modules as $module){
|
||||
$html .= $module->getHTML()."\r\n";
|
||||
}
|
||||
return $html;
|
||||
}
|
||||
|
||||
public function getTabPagesHTML(){
|
||||
$html = "";
|
||||
foreach($this->modules as $module){
|
||||
if(get_class($module) == "ModuleTab"){
|
||||
$html .= $module->getPageHTML()."\r\n";
|
||||
}else{
|
||||
foreach($module->modules as $mod){
|
||||
$html .= $mod->getPageHTML()."\r\n";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return $html;
|
||||
}
|
||||
|
||||
public function getModJsHTML(){
|
||||
$html = "var modJsList = new Array();\r\n";
|
||||
$activeModule = "";
|
||||
foreach($this->modules as $module){
|
||||
if(get_class($module) == "ModuleTab"){
|
||||
$html .= $module->getJSObjectCode()."\r\n";
|
||||
if($module->isActive){
|
||||
$activeModule = $module->name;
|
||||
}
|
||||
}else{
|
||||
|
||||
foreach($module->modules as $mod){
|
||||
if($module->isActive && $activeModule == ""){
|
||||
$activeModule = $mod->name;
|
||||
}
|
||||
$html .= $mod->getJSObjectCode()."\r\n";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$html .= "var modJs = modJsList['tab".$activeModule."'];\r\n";
|
||||
return $html;
|
||||
}
|
||||
}
|
||||
|
||||
class ModuleTab{
|
||||
public $name;
|
||||
var $class;
|
||||
var $label;
|
||||
var $adapterName;
|
||||
var $filter;
|
||||
var $orderBy;
|
||||
public $isActive = false;
|
||||
public $isInsideGroup = false;
|
||||
var $options = array();
|
||||
|
||||
public function __construct($name, $class, $label, $adapterName, $filter, $orderBy, $isActive = false, $options = array()){
|
||||
$this->name = $name;
|
||||
$this->class = $class;
|
||||
$this->label = $label;
|
||||
$this->adapterName = $adapterName;
|
||||
$this->filter = $filter;
|
||||
$this->orderBy = $orderBy;
|
||||
$this->isActive = $isActive;
|
||||
$this->options = $options;
|
||||
}
|
||||
|
||||
public function getHTML(){
|
||||
$active = ($this->isActive)?"active":"";
|
||||
if(!$this->isInsideGroup) {
|
||||
return '<li class="' . $active . '"><a id="tab' . $this->name . '" href="#tabPage' . $this->name . '">' . $this->label . '</a></li>';
|
||||
}else{
|
||||
return '<li class="' . $active . '"><a id="tab' . $this->name . '" href="#tabPage' . $this->name . '">' . $this->label . '</a></li>';
|
||||
}
|
||||
}
|
||||
|
||||
public function getPageHTML(){
|
||||
$active = ($this->isActive)?" active":"";
|
||||
$html = '<div class="tab-pane'.$active.'" id="tabPage'.$this->name.'">'.
|
||||
'<div id="'.$this->name.'" class="reviewBlock" data-content="List" style="padding-left:5px;"></div>'.
|
||||
'<div id="'.$this->name.'Form" class="reviewBlock" data-content="Form" style="padding-left:5px;display:none;"></div>'.
|
||||
'</div>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
public function getJSObjectCode()
|
||||
{
|
||||
$js = '';
|
||||
if (empty($this->filter)) {
|
||||
$js.= "modJsList['tab" . $this->name . "'] = new " . $this->adapterName . "('" . $this->class . "','" . $this->name . "','','".$this->orderBy."');";
|
||||
} else {
|
||||
$js.= "modJsList['tab" . $this->name . "'] = new " . $this->adapterName . "('" . $this->class . "','" . $this->name . "'," . $this->filter . ",'".$this->orderBy."');";
|
||||
}
|
||||
|
||||
foreach($this->options as $key => $val){
|
||||
$js.= "modJsList['tab" . $this->name . "'].".$key."(".$val.");";
|
||||
}
|
||||
|
||||
return $js;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ModuleTabGroup{
|
||||
var $name;
|
||||
var $label;
|
||||
var $isActive = false;
|
||||
public $modules = array();
|
||||
|
||||
public function __construct($name, $label){
|
||||
$this->name = $name;
|
||||
$this->label = $label;
|
||||
}
|
||||
|
||||
public function addModuleTab($moduleTab){
|
||||
if($moduleTab->isActive){
|
||||
$this->isActive = true;
|
||||
$moduleTab->isActive = false;
|
||||
}
|
||||
$moduleTab->isInsideGroup = true;
|
||||
$this->modules[] = $moduleTab;
|
||||
}
|
||||
|
||||
public function getHTML(){
|
||||
$html = "";
|
||||
$active = ($this->isActive)?" active":"";
|
||||
|
||||
$html.= '<li class="dropdown'.$active.'">'."\r\n".
|
||||
'<a href="#" id="'.$this->name.'" class="dropdown-toggle" data-toggle="dropdown" aria-controls="'.$this->name.'-contents">'.$this->label.' <span class="caret"></span></a>'."\r\n".
|
||||
'<ul class="dropdown-menu" role="menu" aria-labelledby="'.$this->name.'" id="'.$this->name.'-contents">';
|
||||
|
||||
foreach($this->modules as $module){
|
||||
$html.= $module->getHTML();
|
||||
}
|
||||
|
||||
$html .= "</ul></li>";
|
||||
|
||||
return $html;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
78
src/classes/NotificationManager.php
Normal file
78
src/classes/NotificationManager.php
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
class NotificationManager{
|
||||
|
||||
var $baseService;
|
||||
|
||||
public function setBaseService($baseService){
|
||||
$this->baseService = $baseService;
|
||||
}
|
||||
|
||||
public function addNotification($toUser, $message, $action, $type){
|
||||
$profileVar = SIGN_IN_ELEMENT_MAPPING_FIELD_NAME;
|
||||
$profileClass = ucfirst(SIGN_IN_ELEMENT_MAPPING_FIELD_NAME);
|
||||
$userEmp = new User();
|
||||
$userEmp->load("profile = ?",array($toUser));
|
||||
|
||||
if(!empty($userEmp->$profileVar) && $userEmp->$profileVar == $toUser){
|
||||
$toUser = $userEmp->id;
|
||||
}else{
|
||||
return;
|
||||
}
|
||||
|
||||
$noti = new Notification();
|
||||
$user = $this->baseService->getCurrentUser();
|
||||
$noti->fromUser = $user->id;
|
||||
$noti->fromProfile = $user->$profileVar;
|
||||
$noti->toUser = $toUser;
|
||||
$noti->message = $message;
|
||||
|
||||
if(!empty($noti->fromProfile)){
|
||||
$profile = $this->baseService->getElement($profileClass,$noti->fromProfile,null,true);
|
||||
if(!empty($profile)){
|
||||
$fs = new FileService();
|
||||
$profile = $fs->updateProfileImage($profile);
|
||||
$noti->image = $profile->image;
|
||||
}
|
||||
}
|
||||
|
||||
if(empty($noti->image)){
|
||||
$noti->image = BASE_URL."images/user_male.png";
|
||||
}
|
||||
|
||||
$noti->action = $action;
|
||||
$noti->type = $type;
|
||||
$noti->time = date('Y-m-d H:i:s');
|
||||
$noti->status = 'Unread';
|
||||
|
||||
$ok = $noti->Save();
|
||||
if(!$ok){
|
||||
LogManager::getInstance()->info("Error adding notification: ".$noti->ErrorMsg());
|
||||
}
|
||||
}
|
||||
|
||||
public function clearNotifications($userId){
|
||||
$notification = new Notification();
|
||||
|
||||
$listUnread = $notification->Find("toUser = ? and status = ?",array($userId,'Unread'));
|
||||
|
||||
foreach($listUnread as $not){
|
||||
$not->status = "Read";
|
||||
$not->Save();
|
||||
}
|
||||
}
|
||||
|
||||
public function getLatestNotificationsAndCounts($userId){
|
||||
$notification = new Notification();
|
||||
|
||||
$listUnread = $notification->Find("toUser = ? and status = ?",array($userId,'Unread'));
|
||||
$unreadCount = count($listUnread);
|
||||
|
||||
$limit = ($unreadCount < 20)?20:$unreadCount;
|
||||
|
||||
$list = $notification->Find("toUser = ? order by time desc limit ?",array($userId,$limit));
|
||||
|
||||
return array($unreadCount, $list);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
143
src/classes/ReportHandler.php
Normal file
143
src/classes/ReportHandler.php
Normal file
@@ -0,0 +1,143 @@
|
||||
<?php
|
||||
class ReportHandler{
|
||||
public function handleReport($request){
|
||||
if(!empty($request['id'])){
|
||||
$report = new Report();
|
||||
$report->Load("id = ?",array($request['id']));
|
||||
if($report->id."" == $request['id']){
|
||||
|
||||
if($report->type == 'Query'){
|
||||
$where = $this->buildQueryOmmit(json_decode($report->paramOrder,true), $request);
|
||||
$query = str_replace("_where_", $where[0], $report->query);
|
||||
return $this->executeReport($report,$query,$where[1]);
|
||||
}else if($report->type == 'Class'){
|
||||
$className = $report->query;
|
||||
include MODULE_PATH.'/reportClasses/ReportBuilder.php';
|
||||
include MODULE_PATH.'/reportClasses/'.$className.".php";
|
||||
$cls = new $className();
|
||||
$data = $cls->getData($report,$request);
|
||||
return $this->generateReport($report,$data);
|
||||
}
|
||||
}else{
|
||||
return array("ERROR","Report id not found");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private function executeReport($report,$query,$parameters){
|
||||
|
||||
$report->DB()->SetFetchMode(ADODB_FETCH_ASSOC);
|
||||
$rs = $report->DB()->Execute($query,$parameters);
|
||||
if(!$rs){
|
||||
LogManager::getInstance()->info($report->DB()->ErrorMsg());
|
||||
return array("ERROR","Error generating report");
|
||||
}
|
||||
|
||||
$reportNamesFilled = false;
|
||||
$columnNames = array();
|
||||
$reportData = array();
|
||||
foreach ($rs as $rowId => $row) {
|
||||
$reportData[] = array();
|
||||
if(!$reportNamesFilled){
|
||||
foreach ($row as $name=> $value){
|
||||
$columnNames[] = $name;
|
||||
$reportData[count($reportData)-1][] = $value;
|
||||
}
|
||||
$reportNamesFilled = true;
|
||||
}else{
|
||||
foreach ($row as $name=> $value){
|
||||
$reportData[count($reportData)-1][] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
array_unshift($reportData,$columnNames);
|
||||
|
||||
return $this->generateReport($report, $reportData);
|
||||
|
||||
|
||||
}
|
||||
|
||||
private function generateReport($report, $data){
|
||||
|
||||
$fileFirst = "Report_".str_replace(" ", "_", $report->name)."-".date("Y-m-d_H-i-s");
|
||||
$file = $fileFirst.".csv";
|
||||
|
||||
$fileName = CLIENT_BASE_PATH.'data/'.$file;
|
||||
$fp = fopen($fileName, 'w');
|
||||
|
||||
foreach ($data as $fields) {
|
||||
fputcsv($fp, $fields);
|
||||
}
|
||||
|
||||
fclose($fp);
|
||||
|
||||
$uploadedToS3 = false;
|
||||
|
||||
$uploadFilesToS3 = SettingsManager::getInstance()->getSetting("Files: Upload Files to S3");
|
||||
$uploadFilesToS3Key = SettingsManager::getInstance()->getSetting("Files: Amazon S3 Key for File Upload");
|
||||
$uploadFilesToS3Secret = SettingsManager::getInstance()->getSetting("Files: Amazone S3 Secret for File Upload");
|
||||
$s3Bucket = SettingsManager::getInstance()->getSetting("Files: S3 Bucket");
|
||||
$s3WebUrl = SettingsManager::getInstance()->getSetting("Files: S3 Web Url");
|
||||
|
||||
if($uploadFilesToS3.'' == '1' && !empty($uploadFilesToS3Key)
|
||||
&& !empty($uploadFilesToS3Secret) && !empty($s3Bucket) && !empty($s3WebUrl)){
|
||||
|
||||
$uploadname = CLIENT_NAME."/".$file;
|
||||
$s3FileSys = new S3FileSystem($uploadFilesToS3Key, $uploadFilesToS3Secret);
|
||||
$res = $s3FileSys->putObject($s3Bucket, $uploadname, $fileName, 'authenticated-read');
|
||||
|
||||
if(empty($res)){
|
||||
return array("ERROR",$file);
|
||||
}
|
||||
|
||||
unlink($fileName);
|
||||
$file_url = $s3WebUrl.$uploadname;
|
||||
$file_url = $s3FileSys->generateExpiringURL($file_url);
|
||||
$uploadedToS3 = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
$fileObj = new File();
|
||||
$fileObj->name = $fileFirst;
|
||||
$fileObj->filename = $file;
|
||||
$fileObj->file_group = "Report";
|
||||
$ok = $fileObj->Save();
|
||||
|
||||
if(!$ok){
|
||||
LogManager::getInstance()->info($fileObj->ErrorMsg());
|
||||
return array("ERROR","Error generating report");
|
||||
}
|
||||
|
||||
$headers = array_shift($data);
|
||||
if($uploadedToS3){
|
||||
return array("SUCCESS",array($file_url,$headers,$data));
|
||||
}else{
|
||||
return array("SUCCESS",array($file,$headers,$data));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function buildQueryOmmit($names, $params){
|
||||
$parameters = array();
|
||||
$query = "";
|
||||
foreach($names as $name){
|
||||
if($params[$name] != "NULL"){
|
||||
if($query != ""){
|
||||
$query.=" AND ";
|
||||
}
|
||||
$query.=$name." = ?";
|
||||
$parameters[] = $params[$name];
|
||||
}
|
||||
}
|
||||
|
||||
if($query != ""){
|
||||
$query = "where ".$query;
|
||||
}
|
||||
|
||||
return array($query, $parameters);
|
||||
}
|
||||
}
|
||||
151
src/classes/RestApiManager.php
Normal file
151
src/classes/RestApiManager.php
Normal file
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
class RestApiManager{
|
||||
|
||||
private static $me = NULL;
|
||||
|
||||
var $endPoints = array();
|
||||
|
||||
private function __construct(){
|
||||
|
||||
}
|
||||
|
||||
public static function getInstance(){
|
||||
if(empty(self::$me)){
|
||||
self::$me = new RestApiManager();
|
||||
}
|
||||
|
||||
return self::$me;
|
||||
}
|
||||
|
||||
public function generateUserAccessToken($user){
|
||||
|
||||
$data = array();
|
||||
$data['userId'] = $user->id;
|
||||
$data['expires'] = strtotime('now') + 60*60;
|
||||
|
||||
$accessTokenTemp = AesCtr::encrypt(json_encode($data), $user->password, 256);
|
||||
$accessTokenTemp = $user->id."|".$accessTokenTemp;
|
||||
$accessToken = AesCtr::encrypt($accessTokenTemp, APP_SEC, 256);
|
||||
|
||||
return new IceResponse(IceResponse::SUCCESS, $accessToken);
|
||||
}
|
||||
|
||||
public function getAccessTokenForUser($user){
|
||||
$accessTokenObj = new RestAccessToken();
|
||||
$accessTokenObj->Load("userId = ?",array($user->id));
|
||||
|
||||
$generateAccessToken = false;
|
||||
$accessToken = $accessTokenObj->token;
|
||||
if(!empty($accessToken)){
|
||||
$resp = $this->validateAccessTokenInner($accessToken);
|
||||
if($resp->getStatus() != IceResponse::SUCCESS){
|
||||
$generateAccessToken = true;
|
||||
}
|
||||
}else{
|
||||
$generateAccessToken = true;
|
||||
}
|
||||
|
||||
if($generateAccessToken){
|
||||
$accessToken = $this->generateUserAccessToken($user)->getData();
|
||||
if(!empty($accessTokenObj->id)){
|
||||
$accessTokenObj->token = $accessToken;
|
||||
$accessTokenObj->hash = base64_encode(CLIENT_BASE_URL).":".md5($accessTokenObj->token);
|
||||
$accessTokenObj->updated = date("Y-m-d H:i:s");
|
||||
$accessTokenObj->Save();
|
||||
}else{
|
||||
$accessTokenObj = new RestAccessToken();
|
||||
$accessTokenObj->userId = $user->id;
|
||||
$accessTokenObj->token = $accessToken;
|
||||
$accessTokenObj->hash = base64_encode(CLIENT_BASE_URL).":".md5($accessTokenObj->token);
|
||||
$accessTokenObj->updated = date("Y-m-d H:i:s");
|
||||
$accessTokenObj->created = date("Y-m-d H:i:s");
|
||||
$accessTokenObj->Save();
|
||||
}
|
||||
}
|
||||
|
||||
return new IceResponse(IceResponse::SUCCESS, $accessTokenObj->hash);
|
||||
}
|
||||
|
||||
|
||||
public function validateAccessToken($hash){
|
||||
$accessTokenObj = new RestAccessToken();
|
||||
$accessTokenObj->Load("hash = ?",array($hash));
|
||||
|
||||
if(!empty($accessTokenObj->id) && $accessTokenObj->hash == $hash){
|
||||
return $this->validateAccessTokenInner($accessTokenObj->token);
|
||||
}
|
||||
|
||||
return new IceResponse(IceResponse::ERROR, "Acess Token not found");
|
||||
}
|
||||
|
||||
private function validateAccessTokenInner($accessToken){
|
||||
$accessTokenTemp = AesCtr::decrypt($accessToken, APP_SEC, 256);
|
||||
$parts = explode("|", $accessTokenTemp);
|
||||
|
||||
$user = new User();
|
||||
$user->Load("id = ?",array($parts[0]));
|
||||
if(empty($user->id) || $user->id != $parts[0] || empty($parts[0])){
|
||||
return new IceResponse(IceResponse::ERROR, -1);
|
||||
}
|
||||
|
||||
$accessToken = AesCtr::decrypt($parts[1], $user->password, 256);
|
||||
|
||||
$data = json_decode($accessToken, true);
|
||||
if($data['userId'] == $user->id){
|
||||
return new IceResponse(IceResponse::SUCCESS, true);
|
||||
}
|
||||
|
||||
return new IceResponse(IceResponse::ERROR, false);
|
||||
}
|
||||
|
||||
public function addEndPoint($endPoint){
|
||||
$url = $endPoint->getUrl();
|
||||
LogManager::getInstance()->info("Adding REST end point for - ".$url);
|
||||
$this->endPoints[$url] = $endPoint;
|
||||
}
|
||||
|
||||
public function process($type, $url, $parameters){
|
||||
|
||||
$accessTokenValidation = $this->validateAccessToken($parameters['access_token']);
|
||||
|
||||
if($accessTokenValidation->getStatus() == IceResponse::ERROR){
|
||||
return $accessTokenValidation;
|
||||
}
|
||||
|
||||
if(isset($this->endPoints[$url])){
|
||||
return $this->endPoints[$url]->$type($parameters);
|
||||
}
|
||||
|
||||
return new IceResponse(IceResponse::ERROR, "End Point ".$url." - Not Found");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class RestEndPoint{
|
||||
var $url;
|
||||
|
||||
public function setUrl($url){
|
||||
$this->url = $url;
|
||||
}
|
||||
|
||||
public function getUrl(){
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
public function get($parameters){
|
||||
return new IceResponse(IceResponse::ERROR, false);
|
||||
}
|
||||
|
||||
public function post($parameters){
|
||||
return new IceResponse(IceResponse::ERROR, false);
|
||||
}
|
||||
|
||||
public function put($parameters){
|
||||
return new IceResponse(IceResponse::ERROR, false);
|
||||
}
|
||||
|
||||
public function delete($parameters){
|
||||
return new IceResponse(IceResponse::ERROR, false);
|
||||
}
|
||||
}
|
||||
|
||||
107
src/classes/S3FileSystem.php
Normal file
107
src/classes/S3FileSystem.php
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
use Aws\S3\S3Client;
|
||||
class S3FileSystem{
|
||||
|
||||
var $s3;
|
||||
var $key;
|
||||
var $secret;
|
||||
|
||||
public function __construct($key, $secret){
|
||||
|
||||
$this->key = $key;
|
||||
$this->secret = $secret;
|
||||
$arr = array(
|
||||
'key' => $key,
|
||||
'secret' => $secret,
|
||||
'region' => AWS_REGION
|
||||
);
|
||||
$this->s3 = S3Client::factory($arr);
|
||||
}
|
||||
|
||||
public function putObject($bucket, $key, $sourceFile, $acl){
|
||||
$res = null;
|
||||
try{
|
||||
$res = $this->s3->putObject(array(
|
||||
'Bucket' => $bucket,
|
||||
'Key' => $key,
|
||||
'SourceFile' => $sourceFile,
|
||||
'ACL' => $acl
|
||||
/*'ContentType' => 'image/jpeg'*/
|
||||
));
|
||||
}catch(Exception $e){
|
||||
LogManager::getInstance()->info($e->getMessage());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LogManager::getInstance()->info("Response from s3:".print_r($res,true));
|
||||
|
||||
$result = $res->get('RequestId');
|
||||
if(!empty($result)){
|
||||
return $result;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
public function deleteObject($bucket, $key){
|
||||
$res = null;
|
||||
|
||||
try{
|
||||
$res = $this->s3->deleteObject(array(
|
||||
'Bucket' => $bucket,
|
||||
'Key' => $key
|
||||
));
|
||||
}catch(Exception $e){
|
||||
LogManager::getInstance()->info($e->getMessage());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LogManager::getInstance()->info("Response from s3:".print_r($res,true));
|
||||
|
||||
$result = $res->get('RequestId');
|
||||
if(!empty($result)){
|
||||
return $result;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
public function generateExpiringURL($url, $expiresIn = 600) {
|
||||
// Calculate expiry time
|
||||
$expiresTimestamp = time() + intval($expiresIn);
|
||||
$path = parse_url($url, PHP_URL_PATH);
|
||||
$path = str_replace('%2F', '/', rawurlencode($path = ltrim($path, '/')));
|
||||
$host = parse_url($url, PHP_URL_HOST);
|
||||
$bucket = str_replace(".s3.amazonaws.com", "", $host);
|
||||
// Path for signature starts with the bucket
|
||||
$signpath = '/'. $bucket .'/'. $path;
|
||||
|
||||
// S3 friendly string to sign
|
||||
$signsz = implode("\n", $pieces = array('GET', null, null, $expiresTimestamp, $signpath));
|
||||
|
||||
// Calculate the hash
|
||||
$signature = $this->el_crypto_hmacSHA1($this->secret, $signsz);
|
||||
// ... to the query string ...
|
||||
$qs = http_build_query($pieces = array(
|
||||
'AWSAccessKeyId' => $this->key,
|
||||
'Expires' => $expiresTimestamp,
|
||||
'Signature' => $signature,
|
||||
));
|
||||
// ... and return the URL!
|
||||
return $url.'?'.$qs;
|
||||
}
|
||||
|
||||
private function el_crypto_hmacSHA1($key, $data, $blocksize = 64) {
|
||||
if (strlen($key) > $blocksize) $key = pack('H*', sha1($key));
|
||||
$key = str_pad($key, $blocksize, chr(0x00));
|
||||
$ipad = str_repeat(chr(0x36), $blocksize);
|
||||
$opad = str_repeat(chr(0x5c), $blocksize);
|
||||
$hmac = pack( 'H*', sha1(
|
||||
($key ^ $opad) . pack( 'H*', sha1(
|
||||
($key ^ $ipad) . $data
|
||||
))
|
||||
));
|
||||
return base64_encode($hmac);
|
||||
}
|
||||
|
||||
}
|
||||
44
src/classes/SettingsManager.php
Normal file
44
src/classes/SettingsManager.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
class SettingsManager{
|
||||
|
||||
private static $me = null;
|
||||
|
||||
private function __construct(){
|
||||
|
||||
}
|
||||
|
||||
public static function getInstance(){
|
||||
if(empty(self::$me)){
|
||||
self::$me = new SettingsManager();
|
||||
}
|
||||
|
||||
return self::$me;
|
||||
}
|
||||
|
||||
public function getSetting($name){
|
||||
|
||||
if(class_exists("ProVersion")){
|
||||
$pro = new ProVersion();
|
||||
$val = $pro->getSetting($name);
|
||||
if(!empty($val)){
|
||||
return $val;
|
||||
}
|
||||
}
|
||||
|
||||
$setting = new Setting();
|
||||
$setting->Load("name = ?",array($name));
|
||||
if($setting->name == $name){
|
||||
return $setting->value;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function setSetting($name, $value){
|
||||
$setting = new Setting();
|
||||
$setting->Load("name = ?",array($name));
|
||||
if($setting->name == $name){
|
||||
$setting->value = $value;
|
||||
$setting->Save();
|
||||
}
|
||||
}
|
||||
}
|
||||
1287
src/classes/SimpleImage.php
Normal file
1287
src/classes/SimpleImage.php
Normal file
File diff suppressed because it is too large
Load Diff
104
src/classes/SubActionManager.php
Normal file
104
src/classes/SubActionManager.php
Normal file
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
/*
|
||||
This file is part of Ice Framework.
|
||||
|
||||
Ice Framework is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Ice Framework is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Ice Framework. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
------------------------------------------------------------------
|
||||
|
||||
Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd]
|
||||
Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah)
|
||||
*/
|
||||
|
||||
class IceResponse{
|
||||
|
||||
const SUCCESS = "SUCCESS";
|
||||
const ERROR = "ERROR";
|
||||
|
||||
var $status;
|
||||
var $data;
|
||||
|
||||
public function __construct($status,$data = null){
|
||||
$this->status = $status;
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
public function getStatus(){
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
public function getData(){
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
public function getObject(){
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
public function getJsonArray(){
|
||||
return array("status"=>$this->status,"data"=>$this->data);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class SubActionManager{
|
||||
var $user = null;
|
||||
protected $baseService = null;
|
||||
var $emailTemplates = null;
|
||||
var $emailSender = null;
|
||||
|
||||
public function setUser($user){
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
public function setBaseService($baseService){
|
||||
$this->baseService = $baseService;
|
||||
}
|
||||
|
||||
public function getCurrentProfileId(){
|
||||
return $this->baseService->getCurrentProfileId();
|
||||
}
|
||||
|
||||
public function setEmailTemplates($emailTemplates){
|
||||
|
||||
$this->emailTemplates = $emailTemplates;
|
||||
|
||||
}
|
||||
|
||||
public function getEmailTemplate($name){
|
||||
//Read module email templates
|
||||
if($this->emailTemplates == null){
|
||||
$this->emailTemplates = array();
|
||||
if(is_dir(MODULE_PATH.'/emailTemplates/')){
|
||||
$ams = scandir(MODULE_PATH.'/emailTemplates/');
|
||||
foreach($ams as $am){
|
||||
if(!is_dir(MODULE_PATH.'/emailTemplates/'.$am) && $am != '.' && $am != '..'){
|
||||
$this->emailTemplates[$am] = file_get_contents(MODULE_PATH.'/emailTemplates/'.$am);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->emailTemplates[$name];
|
||||
}
|
||||
|
||||
public function setEmailSender($emailSender){
|
||||
$this->emailSender = $emailSender;
|
||||
}
|
||||
|
||||
public function getUserFromProfileId($profileId){
|
||||
return $this->baseService->getUserFromProfileId($profileId);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
228
src/classes/UIManager.php
Normal file
228
src/classes/UIManager.php
Normal file
@@ -0,0 +1,228 @@
|
||||
<?php
|
||||
class UIManager{
|
||||
|
||||
private static $me = null;
|
||||
|
||||
var $user;
|
||||
var $currentProfile;
|
||||
var $switchedProfile;
|
||||
|
||||
var $currentProfileBlock = null;
|
||||
var $switchedProfileBlock = null;
|
||||
|
||||
var $tempates = array();
|
||||
|
||||
var $quickAccessMenuItems = array();
|
||||
|
||||
|
||||
private function __construct(){
|
||||
|
||||
}
|
||||
|
||||
public static function getInstance(){
|
||||
if(empty(self::$me)){
|
||||
self::$me = new UIManager();
|
||||
}
|
||||
|
||||
return self::$me;
|
||||
}
|
||||
|
||||
private function getTemplate($name, $type){
|
||||
|
||||
if(isset($this->tempates[$name])){
|
||||
return $this->tempates[$name];
|
||||
}
|
||||
|
||||
$this->tempates[$name] = file_get_contents(APP_BASE_PATH."templates/".$type."/".$name.".html");
|
||||
|
||||
return $this->tempates[$name];
|
||||
}
|
||||
|
||||
public function populateTemplate($name, $type, $params){
|
||||
$template= $this->getTemplate($name, $type);
|
||||
foreach($params as $key=>$value){
|
||||
$template = str_replace("#_".$key."_#", $value, $template);
|
||||
}
|
||||
|
||||
return $template;
|
||||
}
|
||||
|
||||
public function setCurrentUser($user){
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
public function setHomeLink($homeLink){
|
||||
$this->homeLink = $homeLink;
|
||||
}
|
||||
|
||||
public function setProfiles($profileCurrent, $profileSwitched){
|
||||
$this->currentProfile = $profileCurrent;
|
||||
$this->switchedProfile = $profileSwitched;
|
||||
|
||||
if(!empty($profileCurrent) && !empty($profileSwitched)){
|
||||
|
||||
$this->currentProfileBlock = array(
|
||||
"profileImage"=>$profileCurrent->image,
|
||||
"firstName"=>$profileCurrent->first_name,
|
||||
"lastName"=>$profileCurrent->last_name
|
||||
);
|
||||
|
||||
$this->switchedProfileBlock = array(
|
||||
"profileImage"=>$profileSwitched->image,
|
||||
"firstName"=>$profileSwitched->first_name,
|
||||
"lastName"=>$profileSwitched->last_name
|
||||
);
|
||||
|
||||
} else if(!empty($profileCurrent)){
|
||||
|
||||
$this->currentProfileBlock = array(
|
||||
"profileImage"=>$profileCurrent->image,
|
||||
"firstName"=>$profileCurrent->first_name,
|
||||
"lastName"=>$profileCurrent->last_name
|
||||
);
|
||||
|
||||
} else if(!empty($profileSwitched)){
|
||||
|
||||
$this->currentProfileBlock = array(
|
||||
"profileImage"=>BASE_URL."images/user_male.png",
|
||||
"firstName"=>$this->user->username,
|
||||
"lastName"=>""
|
||||
);
|
||||
|
||||
$this->switchedProfileBlock = array(
|
||||
"profileImage"=>$profileSwitched->image,
|
||||
"firstName"=>$profileSwitched->first_name,
|
||||
"lastName"=>$profileSwitched->last_name
|
||||
);
|
||||
|
||||
}else{
|
||||
|
||||
$this->currentProfileBlock = array(
|
||||
"profileImage"=>BASE_URL."images/user_male.png",
|
||||
"firstName"=>$this->user->username,
|
||||
"lastName"=>""
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function getProfileBlocks(){
|
||||
$tempateProfileBlock = "";
|
||||
$tempateProfileBlock = $this->populateTemplate('profile_info', 'app', $this->currentProfileBlock);
|
||||
if(!empty($this->switchedProfileBlock)){
|
||||
$tempateProfileBlock .= $this->populateTemplate('switched_profile_info', 'app', $this->switchedProfileBlock);
|
||||
}
|
||||
return $tempateProfileBlock;
|
||||
}
|
||||
|
||||
public function getMenuBlocks(){
|
||||
$manuItems = array();
|
||||
|
||||
if(!empty($this->quickAccessMenuItems)){
|
||||
$itemsHtml = $this->getQuickAccessMenuItemsHTML();
|
||||
if(!empty($itemsHtml)){
|
||||
$manuItems[] = new MenuItemTemplate('menuButtonQuick', array("ITEMS"=>$itemsHtml));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$manuItems[] = new MenuItemTemplate('menuButtonNotification', array());
|
||||
if($this->user->user_level == "Admin"){
|
||||
$manuItems[] = new MenuItemTemplate('menuButtonSwitchProfile', array());
|
||||
}
|
||||
|
||||
if(!empty($this->currentProfile)){
|
||||
|
||||
$manuItems[] = new MenuItemTemplate('menuButtonProfile', array(
|
||||
"profileImage"=>$this->currentProfile->image,
|
||||
"firstName"=>$this->currentProfile->first_name,
|
||||
"lastName"=>$this->currentProfile->last_name,
|
||||
"homeLink"=>$this->homeLink,
|
||||
"CLIENT_BASE_URL"=>CLIENT_BASE_URL
|
||||
|
||||
));
|
||||
}else{
|
||||
|
||||
$manuItems[] = new MenuItemTemplate('menuButtonProfile', array(
|
||||
"profileImage"=>BASE_URL."images/user_male.png",
|
||||
"firstName"=>$this->user->username,
|
||||
"lastName"=>"",
|
||||
"homeLink"=>$this->homeLink,
|
||||
"CLIENT_BASE_URL"=>CLIENT_BASE_URL
|
||||
|
||||
));
|
||||
}
|
||||
|
||||
if($this->user->user_level == "Admin"){
|
||||
$manuItems[] = new MenuItemTemplate('menuButtonHelp', array(
|
||||
"APP_NAME"=>APP_NAME,
|
||||
"VERSION"=>VERSION,
|
||||
"VERSION_DATE"=>VERSION_DATE
|
||||
));
|
||||
}
|
||||
|
||||
return $manuItems;
|
||||
|
||||
}
|
||||
|
||||
public function getMenuItemsHTML(){
|
||||
$menuItems = $this->getMenuBlocks();
|
||||
$menuHtml = "";
|
||||
foreach($menuItems as $item){
|
||||
$menuHtml.=$item->getHtml();
|
||||
}
|
||||
|
||||
return $menuHtml;
|
||||
}
|
||||
|
||||
public function addQuickAccessMenuItem($name, $icon, $link, $userLevels = array()){
|
||||
$this->quickAccessMenuItems[] = array($name, $icon, $link, $userLevels);
|
||||
}
|
||||
|
||||
public function getQuickAccessMenuItemsHTML(){
|
||||
$html = "";
|
||||
$user = BaseService::getInstance()->getCurrentUser();
|
||||
foreach($this->quickAccessMenuItems as $item){
|
||||
if(empty($item[3]) || in_array($user->user_level,$item[3])){
|
||||
$html .= '<a href="'.$item[2].'"><i class="fa '.$item[1].'"></i> '.$item[0].'</a>';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
public function renderModule($moduleBuilder){
|
||||
$str = '<div class="span9"><ul class="nav nav-tabs" id="modTab" style="margin-bottom:0px;margin-left:5px;border-bottom: none;">__tabHeaders__</ul><div class="tab-content">__tabPages__</div></div><script>__tabJs__</script>';
|
||||
$str = str_replace("__tabHeaders__",$moduleBuilder->getTabHeadersHTML(), $str);
|
||||
$str = str_replace("__tabPages__",$moduleBuilder->getTabPagesHTML(), $str);
|
||||
$str = str_replace("__tabJs__",$moduleBuilder->getModJsHTML(), $str);
|
||||
return $str;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Menu Items
|
||||
|
||||
class MenuItemTemplate{
|
||||
|
||||
public $templateName;
|
||||
public $params;
|
||||
|
||||
public function __construct($templateName, $params){
|
||||
$this->templateName = $templateName;
|
||||
$this->params = $params;
|
||||
}
|
||||
|
||||
public function getHtml(){
|
||||
return UIManager::getInstance()->populateTemplate($this->templateName, 'menu', $this->params);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
28
src/classes/UserService.php
Normal file
28
src/classes/UserService.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
/*
|
||||
This file is part of Ice Framework.
|
||||
|
||||
Ice Framework is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Ice Framework is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Ice Framework. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
------------------------------------------------------------------
|
||||
|
||||
Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd]
|
||||
Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah)
|
||||
*/
|
||||
|
||||
class UserService{
|
||||
public function getAuthUser($username, $password){
|
||||
|
||||
}
|
||||
}
|
||||
165
src/classes/crypt/Aes.php
Normal file
165
src/classes/crypt/Aes.php
Normal file
@@ -0,0 +1,165 @@
|
||||
<?php
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
/* AES implementation in PHP (c) Chris Veness 2005-2011. Right of free use is granted for all */
|
||||
/* commercial or non-commercial use under CC-BY licence. No warranty of any form is offered. */
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
class Aes {
|
||||
|
||||
/**
|
||||
* AES Cipher function: encrypt 'input' with Rijndael algorithm
|
||||
*
|
||||
* @param input message as byte-array (16 bytes)
|
||||
* @param w key schedule as 2D byte-array (Nr+1 x Nb bytes) -
|
||||
* generated from the cipher key by keyExpansion()
|
||||
* @return ciphertext as byte-array (16 bytes)
|
||||
*/
|
||||
public static function cipher($input, $w) { // main cipher function [§5.1]
|
||||
$Nb = 4; // block size (in words): no of columns in state (fixed at 4 for AES)
|
||||
$Nr = count($w)/$Nb - 1; // no of rounds: 10/12/14 for 128/192/256-bit keys
|
||||
|
||||
$state = array(); // initialise 4xNb byte-array 'state' with input [§3.4]
|
||||
for ($i=0; $i<4*$Nb; $i++) $state[$i%4][floor($i/4)] = $input[$i];
|
||||
|
||||
$state = self::addRoundKey($state, $w, 0, $Nb);
|
||||
|
||||
for ($round=1; $round<$Nr; $round++) { // apply Nr rounds
|
||||
$state = self::subBytes($state, $Nb);
|
||||
$state = self::shiftRows($state, $Nb);
|
||||
$state = self::mixColumns($state, $Nb);
|
||||
$state = self::addRoundKey($state, $w, $round, $Nb);
|
||||
}
|
||||
|
||||
$state = self::subBytes($state, $Nb);
|
||||
$state = self::shiftRows($state, $Nb);
|
||||
$state = self::addRoundKey($state, $w, $Nr, $Nb);
|
||||
|
||||
$output = array(4*$Nb); // convert state to 1-d array before returning [§3.4]
|
||||
for ($i=0; $i<4*$Nb; $i++) $output[$i] = $state[$i%4][floor($i/4)];
|
||||
return $output;
|
||||
}
|
||||
|
||||
|
||||
private static function addRoundKey($state, $w, $rnd, $Nb) { // xor Round Key into state S [§5.1.4]
|
||||
for ($r=0; $r<4; $r++) {
|
||||
for ($c=0; $c<$Nb; $c++) $state[$r][$c] ^= $w[$rnd*4+$c][$r];
|
||||
}
|
||||
return $state;
|
||||
}
|
||||
|
||||
private static function subBytes($s, $Nb) { // apply SBox to state S [§5.1.1]
|
||||
for ($r=0; $r<4; $r++) {
|
||||
for ($c=0; $c<$Nb; $c++) $s[$r][$c] = self::$sBox[$s[$r][$c]];
|
||||
}
|
||||
return $s;
|
||||
}
|
||||
|
||||
private static function shiftRows($s, $Nb) { // shift row r of state S left by r bytes [§5.1.2]
|
||||
$t = array(4);
|
||||
for ($r=1; $r<4; $r++) {
|
||||
for ($c=0; $c<4; $c++) $t[$c] = $s[$r][($c+$r)%$Nb]; // shift into temp copy
|
||||
for ($c=0; $c<4; $c++) $s[$r][$c] = $t[$c]; // and copy back
|
||||
} // note that this will work for Nb=4,5,6, but not 7,8 (always 4 for AES):
|
||||
return $s; // see fp.gladman.plus.com/cryptography_technology/rijndael/aes.spec.311.pdf
|
||||
}
|
||||
|
||||
private static function mixColumns($s, $Nb) { // combine bytes of each col of state S [§5.1.3]
|
||||
for ($c=0; $c<4; $c++) {
|
||||
$a = array(4); // 'a' is a copy of the current column from 's'
|
||||
$b = array(4); // 'b' is a•{02} in GF(2^8)
|
||||
for ($i=0; $i<4; $i++) {
|
||||
$a[$i] = $s[$i][$c];
|
||||
$b[$i] = $s[$i][$c]&0x80 ? $s[$i][$c]<<1 ^ 0x011b : $s[$i][$c]<<1;
|
||||
}
|
||||
// a[n] ^ b[n] is a•{03} in GF(2^8)
|
||||
$s[0][$c] = $b[0] ^ $a[1] ^ $b[1] ^ $a[2] ^ $a[3]; // 2*a0 + 3*a1 + a2 + a3
|
||||
$s[1][$c] = $a[0] ^ $b[1] ^ $a[2] ^ $b[2] ^ $a[3]; // a0 * 2*a1 + 3*a2 + a3
|
||||
$s[2][$c] = $a[0] ^ $a[1] ^ $b[2] ^ $a[3] ^ $b[3]; // a0 + a1 + 2*a2 + 3*a3
|
||||
$s[3][$c] = $a[0] ^ $b[0] ^ $a[1] ^ $a[2] ^ $b[3]; // 3*a0 + a1 + a2 + 2*a3
|
||||
}
|
||||
return $s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Key expansion for Rijndael cipher(): performs key expansion on cipher key
|
||||
* to generate a key schedule
|
||||
*
|
||||
* @param key cipher key byte-array (16 bytes)
|
||||
* @return key schedule as 2D byte-array (Nr+1 x Nb bytes)
|
||||
*/
|
||||
public static function keyExpansion($key) { // generate Key Schedule from Cipher Key [§5.2]
|
||||
$Nb = 4; // block size (in words): no of columns in state (fixed at 4 for AES)
|
||||
$Nk = count($key)/4; // key length (in words): 4/6/8 for 128/192/256-bit keys
|
||||
$Nr = $Nk + 6; // no of rounds: 10/12/14 for 128/192/256-bit keys
|
||||
|
||||
$w = array();
|
||||
$temp = array();
|
||||
|
||||
for ($i=0; $i<$Nk; $i++) {
|
||||
$r = array($key[4*$i], $key[4*$i+1], $key[4*$i+2], $key[4*$i+3]);
|
||||
$w[$i] = $r;
|
||||
}
|
||||
|
||||
for ($i=$Nk; $i<($Nb*($Nr+1)); $i++) {
|
||||
$w[$i] = array();
|
||||
for ($t=0; $t<4; $t++) $temp[$t] = $w[$i-1][$t];
|
||||
if ($i % $Nk == 0) {
|
||||
$temp = self::subWord(self::rotWord($temp));
|
||||
for ($t=0; $t<4; $t++) $temp[$t] ^= self::$rCon[$i/$Nk][$t];
|
||||
} else if ($Nk > 6 && $i%$Nk == 4) {
|
||||
$temp = self::subWord($temp);
|
||||
}
|
||||
for ($t=0; $t<4; $t++) $w[$i][$t] = $w[$i-$Nk][$t] ^ $temp[$t];
|
||||
}
|
||||
return $w;
|
||||
}
|
||||
|
||||
private static function subWord($w) { // apply SBox to 4-byte word w
|
||||
for ($i=0; $i<4; $i++) $w[$i] = self::$sBox[$w[$i]];
|
||||
return $w;
|
||||
}
|
||||
|
||||
private static function rotWord($w) { // rotate 4-byte word w left by one byte
|
||||
$tmp = $w[0];
|
||||
for ($i=0; $i<3; $i++) $w[$i] = $w[$i+1];
|
||||
$w[3] = $tmp;
|
||||
return $w;
|
||||
}
|
||||
|
||||
// sBox is pre-computed multiplicative inverse in GF(2^8) used in subBytes and keyExpansion [§5.1.1]
|
||||
private static $sBox = array(
|
||||
0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,
|
||||
0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,
|
||||
0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15,
|
||||
0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,
|
||||
0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,
|
||||
0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf,
|
||||
0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8,
|
||||
0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2,
|
||||
0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73,
|
||||
0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb,
|
||||
0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79,
|
||||
0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08,
|
||||
0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a,
|
||||
0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e,
|
||||
0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf,
|
||||
0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16);
|
||||
|
||||
// rCon is Round Constant used for the Key Expansion [1st col is 2^(r-1) in GF(2^8)] [§5.2]
|
||||
private static $rCon = array(
|
||||
array(0x00, 0x00, 0x00, 0x00),
|
||||
array(0x01, 0x00, 0x00, 0x00),
|
||||
array(0x02, 0x00, 0x00, 0x00),
|
||||
array(0x04, 0x00, 0x00, 0x00),
|
||||
array(0x08, 0x00, 0x00, 0x00),
|
||||
array(0x10, 0x00, 0x00, 0x00),
|
||||
array(0x20, 0x00, 0x00, 0x00),
|
||||
array(0x40, 0x00, 0x00, 0x00),
|
||||
array(0x80, 0x00, 0x00, 0x00),
|
||||
array(0x1b, 0x00, 0x00, 0x00),
|
||||
array(0x36, 0x00, 0x00, 0x00) );
|
||||
|
||||
}
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
?>
|
||||
164
src/classes/crypt/AesCtr.php
Normal file
164
src/classes/crypt/AesCtr.php
Normal file
@@ -0,0 +1,164 @@
|
||||
<?php
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
/* AES counter (CTR) mode implementation in PHP (c) Chris Veness 2005-2011. Right of free use is */
|
||||
/* granted for all commercial or non-commercial use under CC-BY licence. No warranty of any */
|
||||
/* form is offered. */
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
class AesCtr extends Aes {
|
||||
|
||||
/**
|
||||
* Encrypt a text using AES encryption in Counter mode of operation
|
||||
* - see http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
|
||||
*
|
||||
* Unicode multi-byte character safe
|
||||
*
|
||||
* @param plaintext source text to be encrypted
|
||||
* @param password the password to use to generate a key
|
||||
* @param nBits number of bits to be used in the key (128, 192, or 256)
|
||||
* @return encrypted text
|
||||
*/
|
||||
public static function encrypt($plaintext, $password, $nBits) {
|
||||
$blockSize = 16; // block size fixed at 16 bytes / 128 bits (Nb=4) for AES
|
||||
if (!($nBits==128 || $nBits==192 || $nBits==256)) return ''; // standard allows 128/192/256 bit keys
|
||||
// note PHP (5) gives us plaintext and password in UTF8 encoding!
|
||||
|
||||
// use AES itself to encrypt password to get cipher key (using plain password as source for
|
||||
// key expansion) - gives us well encrypted key
|
||||
$nBytes = $nBits/8; // no bytes in key
|
||||
$pwBytes = array();
|
||||
for ($i=0; $i<$nBytes; $i++) $pwBytes[$i] = ord(substr($password,$i,1)) & 0xff;
|
||||
$key = Aes::cipher($pwBytes, Aes::keyExpansion($pwBytes));
|
||||
$key = array_merge($key, array_slice($key, 0, $nBytes-16)); // expand key to 16/24/32 bytes long
|
||||
|
||||
// initialise 1st 8 bytes of counter block with nonce (NIST SP800-38A §B.2): [0-1] = millisec,
|
||||
// [2-3] = random, [4-7] = seconds, giving guaranteed sub-ms uniqueness up to Feb 2106
|
||||
$counterBlock = array();
|
||||
$nonce = floor(microtime(true)*1000); // timestamp: milliseconds since 1-Jan-1970
|
||||
$nonceMs = $nonce%1000;
|
||||
$nonceSec = floor($nonce/1000);
|
||||
$nonceRnd = floor(rand(0, 0xffff));
|
||||
|
||||
for ($i=0; $i<2; $i++) $counterBlock[$i] = self::urs($nonceMs, $i*8) & 0xff;
|
||||
for ($i=0; $i<2; $i++) $counterBlock[$i+2] = self::urs($nonceRnd, $i*8) & 0xff;
|
||||
for ($i=0; $i<4; $i++) $counterBlock[$i+4] = self::urs($nonceSec, $i*8) & 0xff;
|
||||
|
||||
// and convert it to a string to go on the front of the ciphertext
|
||||
$ctrTxt = '';
|
||||
for ($i=0; $i<8; $i++) $ctrTxt .= chr($counterBlock[$i]);
|
||||
|
||||
// generate key schedule - an expansion of the key into distinct Key Rounds for each round
|
||||
$keySchedule = Aes::keyExpansion($key);
|
||||
//print_r($keySchedule);
|
||||
|
||||
$blockCount = ceil(strlen($plaintext)/$blockSize);
|
||||
$ciphertxt = array(); // ciphertext as array of strings
|
||||
|
||||
for ($b=0; $b<$blockCount; $b++) {
|
||||
// set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes)
|
||||
// done in two stages for 32-bit ops: using two words allows us to go past 2^32 blocks (68GB)
|
||||
for ($c=0; $c<4; $c++) $counterBlock[15-$c] = self::urs($b, $c*8) & 0xff;
|
||||
for ($c=0; $c<4; $c++) $counterBlock[15-$c-4] = self::urs($b/0x100000000, $c*8);
|
||||
|
||||
$cipherCntr = Aes::cipher($counterBlock, $keySchedule); // -- encrypt counter block --
|
||||
|
||||
// block size is reduced on final block
|
||||
$blockLength = $b<$blockCount-1 ? $blockSize : (strlen($plaintext)-1)%$blockSize+1;
|
||||
$cipherByte = array();
|
||||
|
||||
for ($i=0; $i<$blockLength; $i++) { // -- xor plaintext with ciphered counter byte-by-byte --
|
||||
$cipherByte[$i] = $cipherCntr[$i] ^ ord(substr($plaintext, $b*$blockSize+$i, 1));
|
||||
$cipherByte[$i] = chr($cipherByte[$i]);
|
||||
}
|
||||
$ciphertxt[$b] = implode('', $cipherByte); // escape troublesome characters in ciphertext
|
||||
}
|
||||
|
||||
// implode is more efficient than repeated string concatenation
|
||||
$ciphertext = $ctrTxt . implode('', $ciphertxt);
|
||||
$ciphertext = base64_encode($ciphertext);
|
||||
return $ciphertext;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Decrypt a text encrypted by AES in counter mode of operation
|
||||
*
|
||||
* @param ciphertext source text to be decrypted
|
||||
* @param password the password to use to generate a key
|
||||
* @param nBits number of bits to be used in the key (128, 192, or 256)
|
||||
* @return decrypted text
|
||||
*/
|
||||
public static function decrypt($ciphertext, $password, $nBits) {
|
||||
$blockSize = 16; // block size fixed at 16 bytes / 128 bits (Nb=4) for AES
|
||||
if (!($nBits==128 || $nBits==192 || $nBits==256)) return ''; // standard allows 128/192/256 bit keys
|
||||
$ciphertext = base64_decode($ciphertext);
|
||||
|
||||
// use AES to encrypt password (mirroring encrypt routine)
|
||||
$nBytes = $nBits/8; // no bytes in key
|
||||
$pwBytes = array();
|
||||
for ($i=0; $i<$nBytes; $i++) $pwBytes[$i] = ord(substr($password,$i,1)) & 0xff;
|
||||
$key = Aes::cipher($pwBytes, Aes::keyExpansion($pwBytes));
|
||||
$key = array_merge($key, array_slice($key, 0, $nBytes-16)); // expand key to 16/24/32 bytes long
|
||||
|
||||
// recover nonce from 1st element of ciphertext
|
||||
$counterBlock = array();
|
||||
$ctrTxt = substr($ciphertext, 0, 8);
|
||||
for ($i=0; $i<8; $i++) $counterBlock[$i] = ord(substr($ctrTxt,$i,1));
|
||||
|
||||
// generate key schedule
|
||||
$keySchedule = Aes::keyExpansion($key);
|
||||
|
||||
// separate ciphertext into blocks (skipping past initial 8 bytes)
|
||||
$nBlocks = ceil((strlen($ciphertext)-8) / $blockSize);
|
||||
$ct = array();
|
||||
for ($b=0; $b<$nBlocks; $b++) $ct[$b] = substr($ciphertext, 8+$b*$blockSize, 16);
|
||||
$ciphertext = $ct; // ciphertext is now array of block-length strings
|
||||
|
||||
// plaintext will get generated block-by-block into array of block-length strings
|
||||
$plaintxt = array();
|
||||
|
||||
for ($b=0; $b<$nBlocks; $b++) {
|
||||
// set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes)
|
||||
for ($c=0; $c<4; $c++) $counterBlock[15-$c] = self::urs($b, $c*8) & 0xff;
|
||||
for ($c=0; $c<4; $c++) $counterBlock[15-$c-4] = self::urs(($b+1)/0x100000000-1, $c*8) & 0xff;
|
||||
|
||||
$cipherCntr = Aes::cipher($counterBlock, $keySchedule); // encrypt counter block
|
||||
|
||||
$plaintxtByte = array();
|
||||
for ($i=0; $i<strlen($ciphertext[$b]); $i++) {
|
||||
// -- xor plaintext with ciphered counter byte-by-byte --
|
||||
$plaintxtByte[$i] = $cipherCntr[$i] ^ ord(substr($ciphertext[$b],$i,1));
|
||||
$plaintxtByte[$i] = chr($plaintxtByte[$i]);
|
||||
|
||||
}
|
||||
$plaintxt[$b] = implode('', $plaintxtByte);
|
||||
}
|
||||
|
||||
// join array of blocks into single plaintext string
|
||||
$plaintext = implode('',$plaintxt);
|
||||
|
||||
return $plaintext;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Unsigned right shift function, since PHP has neither >>> operator nor unsigned ints
|
||||
*
|
||||
* @param a number to be shifted (32-bit integer)
|
||||
* @param b number of bits to shift a to the right (0..31)
|
||||
* @return a right-shifted and zero-filled by b bits
|
||||
*/
|
||||
private static function urs($a, $b) {
|
||||
$a &= 0xffffffff; $b &= 0x1f; // (bounds check)
|
||||
if ($a&0x80000000 && $b>0) { // if left-most bit set
|
||||
$a = ($a>>1) & 0x7fffffff; // right-shift one bit & clear left-most bit
|
||||
$a = $a >> ($b-1); // remaining right-shifts
|
||||
} else { // otherwise
|
||||
$a = ($a>>$b); // use normal right-shift
|
||||
}
|
||||
return $a;
|
||||
}
|
||||
|
||||
}
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
?>
|
||||
8
src/composer/composer.json
Normal file
8
src/composer/composer.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"require": {
|
||||
"guzzle/guzzle": "~3.7"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "4.5.*"
|
||||
}
|
||||
}
|
||||
129
src/composer/composer.lock
generated
Normal file
129
src/composer/composer.lock
generated
Normal file
@@ -0,0 +1,129 @@
|
||||
{
|
||||
"_readme": [
|
||||
"This file locks the dependencies of your project to a known state",
|
||||
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"hash": "c6263cc0d124a7e40ee7c52782f80cff",
|
||||
"packages": [
|
||||
{
|
||||
"name": "monolog/monolog",
|
||||
"version": "1.13.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Seldaek/monolog.git",
|
||||
"reference": "c31a2c4e8db5da8b46c74cf275d7f109c0f249ac"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/c31a2c4e8db5da8b46c74cf275d7f109c0f249ac",
|
||||
"reference": "c31a2c4e8db5da8b46c74cf275d7f109c0f249ac",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0",
|
||||
"psr/log": "~1.0"
|
||||
},
|
||||
"provide": {
|
||||
"psr/log-implementation": "1.0.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"aws/aws-sdk-php": "~2.4, >2.4.8",
|
||||
"doctrine/couchdb": "~1.0@dev",
|
||||
"graylog2/gelf-php": "~1.0",
|
||||
"phpunit/phpunit": "~4.0",
|
||||
"raven/raven": "~0.5",
|
||||
"ruflin/elastica": "0.90.*",
|
||||
"swiftmailer/swiftmailer": "~5.3",
|
||||
"videlalvaro/php-amqplib": "~2.4"
|
||||
},
|
||||
"suggest": {
|
||||
"aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
|
||||
"doctrine/couchdb": "Allow sending log messages to a CouchDB server",
|
||||
"ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
|
||||
"ext-mongo": "Allow sending log messages to a MongoDB server",
|
||||
"graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
|
||||
"raven/raven": "Allow sending log messages to a Sentry server",
|
||||
"rollbar/rollbar": "Allow sending log messages to Rollbar",
|
||||
"ruflin/elastica": "Allow sending log messages to an Elastic Search server",
|
||||
"videlalvaro/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.13.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Monolog\\": "src/Monolog"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jordi Boggiano",
|
||||
"email": "j.boggiano@seld.be",
|
||||
"homepage": "http://seld.be"
|
||||
}
|
||||
],
|
||||
"description": "Sends your logs to files, sockets, inboxes, databases and various web services",
|
||||
"homepage": "http://github.com/Seldaek/monolog",
|
||||
"keywords": [
|
||||
"log",
|
||||
"logging",
|
||||
"psr-3"
|
||||
],
|
||||
"time": "2015-03-09 09:58:04"
|
||||
},
|
||||
{
|
||||
"name": "psr/log",
|
||||
"version": "1.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/log.git",
|
||||
"reference": "fe0936ee26643249e916849d48e3a51d5f5e278b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b",
|
||||
"reference": "fe0936ee26643249e916849d48e3a51d5f5e278b",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Psr\\Log\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "http://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interface for logging libraries",
|
||||
"keywords": [
|
||||
"log",
|
||||
"psr",
|
||||
"psr-3"
|
||||
],
|
||||
"time": "2012-12-21 11:40:51"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": [],
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": [],
|
||||
"platform-dev": []
|
||||
}
|
||||
BIN
src/composer/composer.phar
Normal file
BIN
src/composer/composer.phar
Normal file
Binary file not shown.
7
src/composer/vendor/autoload.php
vendored
Normal file
7
src/composer/vendor/autoload.php
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
// autoload.php @generated by Composer
|
||||
|
||||
require_once __DIR__ . '/composer' . '/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInit91d733469d809ee1828b45ab2da48a10::getLoader();
|
||||
413
src/composer/vendor/composer/ClassLoader.php
vendored
Normal file
413
src/composer/vendor/composer/ClassLoader.php
vendored
Normal file
@@ -0,0 +1,413 @@
|
||||
<?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 class loader
|
||||
*
|
||||
* See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md
|
||||
*
|
||||
* $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>
|
||||
*/
|
||||
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;
|
||||
|
||||
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-0 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
// work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731
|
||||
if ('\\' == $class[0]) {
|
||||
$class = substr($class, 1);
|
||||
}
|
||||
|
||||
// class map lookup
|
||||
if (isset($this->classMap[$class])) {
|
||||
return $this->classMap[$class];
|
||||
}
|
||||
if ($this->classMapAuthoritative) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$file = $this->findFileWithExtension($class, '.php');
|
||||
|
||||
// Search for Hack files if we are running on HHVM
|
||||
if ($file === null && defined('HHVM_VERSION')) {
|
||||
$file = $this->findFileWithExtension($class, '.hh');
|
||||
}
|
||||
|
||||
if ($file === null) {
|
||||
// Remember that this class does not exist.
|
||||
return $this->classMap[$class] = false;
|
||||
}
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
private function findFileWithExtension($class, $ext)
|
||||
{
|
||||
// PSR-4 lookup
|
||||
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
|
||||
|
||||
$first = $class[0];
|
||||
if (isset($this->prefixLengthsPsr4[$first])) {
|
||||
foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
|
||||
if (0 === strpos($class, $prefix)) {
|
||||
foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope isolated include.
|
||||
*
|
||||
* Prevents access to $this/self from included files.
|
||||
*/
|
||||
function includeFile($file)
|
||||
{
|
||||
include $file;
|
||||
}
|
||||
9
src/composer/vendor/composer/autoload_classmap.php
vendored
Normal file
9
src/composer/vendor/composer/autoload_classmap.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
// autoload_classmap.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
);
|
||||
10
src/composer/vendor/composer/autoload_namespaces.php
vendored
Normal file
10
src/composer/vendor/composer/autoload_namespaces.php
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
// autoload_namespaces.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'Psr\\Log\\' => array($vendorDir . '/psr/log'),
|
||||
);
|
||||
10
src/composer/vendor/composer/autoload_psr4.php
vendored
Normal file
10
src/composer/vendor/composer/autoload_psr4.php
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
// autoload_psr4.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'),
|
||||
);
|
||||
50
src/composer/vendor/composer/autoload_real.php
vendored
Normal file
50
src/composer/vendor/composer/autoload_real.php
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
// autoload_real.php @generated by Composer
|
||||
|
||||
class ComposerAutoloaderInit91d733469d809ee1828b45ab2da48a10
|
||||
{
|
||||
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('ComposerAutoloaderInit91d733469d809ee1828b45ab2da48a10', 'loadClassLoader'), true, true);
|
||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInit91d733469d809ee1828b45ab2da48a10', 'loadClassLoader'));
|
||||
|
||||
$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;
|
||||
}
|
||||
}
|
||||
|
||||
function composerRequire91d733469d809ee1828b45ab2da48a10($file)
|
||||
{
|
||||
require $file;
|
||||
}
|
||||
117
src/composer/vendor/composer/installed.json
vendored
Normal file
117
src/composer/vendor/composer/installed.json
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
[
|
||||
{
|
||||
"name": "psr/log",
|
||||
"version": "1.0.0",
|
||||
"version_normalized": "1.0.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/log.git",
|
||||
"reference": "fe0936ee26643249e916849d48e3a51d5f5e278b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b",
|
||||
"reference": "fe0936ee26643249e916849d48e3a51d5f5e278b",
|
||||
"shasum": ""
|
||||
},
|
||||
"time": "2012-12-21 11:40:51",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Psr\\Log\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "http://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interface for logging libraries",
|
||||
"keywords": [
|
||||
"log",
|
||||
"psr",
|
||||
"psr-3"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "monolog/monolog",
|
||||
"version": "1.13.1",
|
||||
"version_normalized": "1.13.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Seldaek/monolog.git",
|
||||
"reference": "c31a2c4e8db5da8b46c74cf275d7f109c0f249ac"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/c31a2c4e8db5da8b46c74cf275d7f109c0f249ac",
|
||||
"reference": "c31a2c4e8db5da8b46c74cf275d7f109c0f249ac",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0",
|
||||
"psr/log": "~1.0"
|
||||
},
|
||||
"provide": {
|
||||
"psr/log-implementation": "1.0.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"aws/aws-sdk-php": "~2.4, >2.4.8",
|
||||
"doctrine/couchdb": "~1.0@dev",
|
||||
"graylog2/gelf-php": "~1.0",
|
||||
"phpunit/phpunit": "~4.0",
|
||||
"raven/raven": "~0.5",
|
||||
"ruflin/elastica": "0.90.*",
|
||||
"swiftmailer/swiftmailer": "~5.3",
|
||||
"videlalvaro/php-amqplib": "~2.4"
|
||||
},
|
||||
"suggest": {
|
||||
"aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
|
||||
"doctrine/couchdb": "Allow sending log messages to a CouchDB server",
|
||||
"ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
|
||||
"ext-mongo": "Allow sending log messages to a MongoDB server",
|
||||
"graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
|
||||
"raven/raven": "Allow sending log messages to a Sentry server",
|
||||
"rollbar/rollbar": "Allow sending log messages to Rollbar",
|
||||
"ruflin/elastica": "Allow sending log messages to an Elastic Search server",
|
||||
"videlalvaro/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib"
|
||||
},
|
||||
"time": "2015-03-09 09:58:04",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.13.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Monolog\\": "src/Monolog"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jordi Boggiano",
|
||||
"email": "j.boggiano@seld.be",
|
||||
"homepage": "http://seld.be"
|
||||
}
|
||||
],
|
||||
"description": "Sends your logs to files, sockets, inboxes, databases and various web services",
|
||||
"homepage": "http://github.com/Seldaek/monolog",
|
||||
"keywords": [
|
||||
"log",
|
||||
"logging",
|
||||
"psr-3"
|
||||
]
|
||||
}
|
||||
]
|
||||
15
src/composer/vendor/monolog/monolog/.php_cs
vendored
Normal file
15
src/composer/vendor/monolog/monolog/.php_cs
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
$finder = Symfony\CS\Finder\DefaultFinder::create()
|
||||
->files()
|
||||
->name('*.php')
|
||||
->in(__DIR__.'/src')
|
||||
->in(__DIR__.'/tests')
|
||||
;
|
||||
|
||||
return Symfony\CS\Config\Config::create()
|
||||
->fixers(array(
|
||||
'psr0', 'encoding', 'short_tag', 'braces', 'elseif', 'eof_ending', 'function_declaration', 'indentation', 'line_after_namespace', 'linefeed', 'lowercase_constants', 'lowercase_keywords', 'multiple_use', 'php_closing_tag', 'trailing_spaces', 'visibility', 'duplicate_semicolon', 'extra_empty_lines', 'include', 'namespace_no_leading_whitespace', 'object_operator', 'operators_spaces', 'phpdoc_params', 'return', 'single_array_no_trailing_comma', 'spaces_cast', 'standardize_not_equal', 'ternary_spaces', 'unused_use', 'whitespacy_lines',
|
||||
))
|
||||
->finder($finder)
|
||||
;
|
||||
217
src/composer/vendor/monolog/monolog/CHANGELOG.mdown
vendored
Normal file
217
src/composer/vendor/monolog/monolog/CHANGELOG.mdown
vendored
Normal file
@@ -0,0 +1,217 @@
|
||||
### 1.13.1 (2015-03-09)
|
||||
|
||||
* Fixed regression in HipChat requiring a new token to be created
|
||||
|
||||
### 1.13.0 (2015-03-05)
|
||||
|
||||
* Added Registry::hasLogger to check for the presence of a logger instance
|
||||
* Added context.user support to RavenHandler
|
||||
* Added HipChat API v2 support in the HipChatHandler
|
||||
* Added NativeMailerHandler::addParameter to pass params to the mail() process
|
||||
* Added context data to SlackHandler when $includeContextAndExtra is true
|
||||
* Added ability to customize the Swift_Message per-email in SwiftMailerHandler
|
||||
* Fixed SwiftMailerHandler to lazily create message instances if a callback is provided
|
||||
* Fixed serialization of INF and NaN values in Normalizer and LineFormatter
|
||||
|
||||
### 1.12.0 (2014-12-29)
|
||||
|
||||
* Break: HandlerInterface::isHandling now receives a partial record containing only a level key. This was always the intent and does not break any Monolog handler but is strictly speaking a BC break and you should check if you relied on any other field in your own handlers.
|
||||
* Added PsrHandler to forward records to another PSR-3 logger
|
||||
* Added SamplingHandler to wrap around a handler and include only every Nth record
|
||||
* Added MongoDBFormatter to support better storage with MongoDBHandler (it must be enabled manually for now)
|
||||
* Added exception codes in the output of most formatters
|
||||
* Added LineFormatter::includeStacktraces to enable exception stack traces in logs (uses more than one line)
|
||||
* Added $useShortAttachment to SlackHandler to minify attachment size and $includeExtra to append extra data
|
||||
* Added $host to HipChatHandler for users of private instances
|
||||
* Added $transactionName to NewRelicHandler and support for a transaction_name context value
|
||||
* Fixed MandrillHandler to avoid outputing API call responses
|
||||
* Fixed some non-standard behaviors in SyslogUdpHandler
|
||||
|
||||
### 1.11.0 (2014-09-30)
|
||||
|
||||
* Break: The NewRelicHandler extra and context data are now prefixed with extra_ and context_ to avoid clashes. Watch out if you have scripts reading those from the API and rely on names
|
||||
* Added WhatFailureGroupHandler to suppress any exception coming from the wrapped handlers and avoid chain failures if a logging service fails
|
||||
* Added MandrillHandler to send emails via the Mandrillapp.com API
|
||||
* Added SlackHandler to log records to a Slack.com account
|
||||
* Added FleepHookHandler to log records to a Fleep.io account
|
||||
* Added LogglyHandler::addTag to allow adding tags to an existing handler
|
||||
* Added $ignoreEmptyContextAndExtra to LineFormatter to avoid empty [] at the end
|
||||
* Added $useLocking to StreamHandler and RotatingFileHandler to enable flock() while writing
|
||||
* Added support for PhpAmqpLib in the AmqpHandler
|
||||
* Added FingersCrossedHandler::clear and BufferHandler::clear to reset them between batches in long running jobs
|
||||
* Added support for adding extra fields from $_SERVER in the WebProcessor
|
||||
* Fixed support for non-string values in PrsLogMessageProcessor
|
||||
* Fixed SwiftMailer messages being sent with the wrong date in long running scripts
|
||||
* Fixed minor PHP 5.6 compatibility issues
|
||||
* Fixed BufferHandler::close being called twice
|
||||
|
||||
### 1.10.0 (2014-06-04)
|
||||
|
||||
* Added Logger::getHandlers() and Logger::getProcessors() methods
|
||||
* Added $passthruLevel argument to FingersCrossedHandler to let it always pass some records through even if the trigger level is not reached
|
||||
* Added support for extra data in NewRelicHandler
|
||||
* Added $expandNewlines flag to the ErrorLogHandler to create multiple log entries when a message has multiple lines
|
||||
|
||||
### 1.9.1 (2014-04-24)
|
||||
|
||||
* Fixed regression in RotatingFileHandler file permissions
|
||||
* Fixed initialization of the BufferHandler to make sure it gets flushed after receiving records
|
||||
* Fixed ChromePHPHandler and FirePHPHandler's activation strategies to be more conservative
|
||||
|
||||
### 1.9.0 (2014-04-20)
|
||||
|
||||
* Added LogEntriesHandler to send logs to a LogEntries account
|
||||
* Added $filePermissions to tweak file mode on StreamHandler and RotatingFileHandler
|
||||
* Added $useFormatting flag to MemoryProcessor to make it send raw data in bytes
|
||||
* Added support for table formatting in FirePHPHandler via the table context key
|
||||
* Added a TagProcessor to add tags to records, and support for tags in RavenHandler
|
||||
* Added $appendNewline flag to the JsonFormatter to enable using it when logging to files
|
||||
* Added sound support to the PushoverHandler
|
||||
* Fixed multi-threading support in StreamHandler
|
||||
* Fixed empty headers issue when ChromePHPHandler received no records
|
||||
* Fixed default format of the ErrorLogHandler
|
||||
|
||||
### 1.8.0 (2014-03-23)
|
||||
|
||||
* Break: the LineFormatter now strips newlines by default because this was a bug, set $allowInlineLineBreaks to true if you need them
|
||||
* Added BrowserConsoleHandler to send logs to any browser's console via console.log() injection in the output
|
||||
* Added FilterHandler to filter records and only allow those of a given list of levels through to the wrapped handler
|
||||
* Added FlowdockHandler to send logs to a Flowdock account
|
||||
* Added RollbarHandler to send logs to a Rollbar account
|
||||
* Added HtmlFormatter to send prettier log emails with colors for each log level
|
||||
* Added GitProcessor to add the current branch/commit to extra record data
|
||||
* Added a Monolog\Registry class to allow easier global access to pre-configured loggers
|
||||
* Added support for the new official graylog2/gelf-php lib for GelfHandler, upgrade if you can by replacing the mlehner/gelf-php requirement
|
||||
* Added support for HHVM
|
||||
* Added support for Loggly batch uploads
|
||||
* Added support for tweaking the content type and encoding in NativeMailerHandler
|
||||
* Added $skipClassesPartials to tweak the ignored classes in the IntrospectionProcessor
|
||||
* Fixed batch request support in GelfHandler
|
||||
|
||||
### 1.7.0 (2013-11-14)
|
||||
|
||||
* Added ElasticSearchHandler to send logs to an Elastic Search server
|
||||
* Added DynamoDbHandler and ScalarFormatter to send logs to Amazon's Dynamo DB
|
||||
* Added SyslogUdpHandler to send logs to a remote syslogd server
|
||||
* Added LogglyHandler to send logs to a Loggly account
|
||||
* Added $level to IntrospectionProcessor so it only adds backtraces when needed
|
||||
* Added $version to LogstashFormatter to allow using the new v1 Logstash format
|
||||
* Added $appName to NewRelicHandler
|
||||
* Added configuration of Pushover notification retries/expiry
|
||||
* Added $maxColumnWidth to NativeMailerHandler to change the 70 chars default
|
||||
* Added chainability to most setters for all handlers
|
||||
* Fixed RavenHandler batch processing so it takes the message from the record with highest priority
|
||||
* Fixed HipChatHandler batch processing so it sends all messages at once
|
||||
* Fixed issues with eAccelerator
|
||||
* Fixed and improved many small things
|
||||
|
||||
### 1.6.0 (2013-07-29)
|
||||
|
||||
* Added HipChatHandler to send logs to a HipChat chat room
|
||||
* Added ErrorLogHandler to send logs to PHP's error_log function
|
||||
* Added NewRelicHandler to send logs to NewRelic's service
|
||||
* Added Monolog\ErrorHandler helper class to register a Logger as exception/error/fatal handler
|
||||
* Added ChannelLevelActivationStrategy for the FingersCrossedHandler to customize levels by channel
|
||||
* Added stack traces output when normalizing exceptions (json output & co)
|
||||
* Added Monolog\Logger::API constant (currently 1)
|
||||
* Added support for ChromePHP's v4.0 extension
|
||||
* Added support for message priorities in PushoverHandler, see $highPriorityLevel and $emergencyLevel
|
||||
* Added support for sending messages to multiple users at once with the PushoverHandler
|
||||
* Fixed RavenHandler's support for batch sending of messages (when behind a Buffer or FingersCrossedHandler)
|
||||
* Fixed normalization of Traversables with very large data sets, only the first 1000 items are shown now
|
||||
* Fixed issue in RotatingFileHandler when an open_basedir restriction is active
|
||||
* Fixed minor issues in RavenHandler and bumped the API to Raven 0.5.0
|
||||
* Fixed SyslogHandler issue when many were used concurrently with different facilities
|
||||
|
||||
### 1.5.0 (2013-04-23)
|
||||
|
||||
* Added ProcessIdProcessor to inject the PID in log records
|
||||
* Added UidProcessor to inject a unique identifier to all log records of one request/run
|
||||
* Added support for previous exceptions in the LineFormatter exception serialization
|
||||
* Added Monolog\Logger::getLevels() to get all available levels
|
||||
* Fixed ChromePHPHandler so it avoids sending headers larger than Chrome can handle
|
||||
|
||||
### 1.4.1 (2013-04-01)
|
||||
|
||||
* Fixed exception formatting in the LineFormatter to be more minimalistic
|
||||
* Fixed RavenHandler's handling of context/extra data, requires Raven client >0.1.0
|
||||
* Fixed log rotation in RotatingFileHandler to work with long running scripts spanning multiple days
|
||||
* Fixed WebProcessor array access so it checks for data presence
|
||||
* Fixed Buffer, Group and FingersCrossed handlers to make use of their processors
|
||||
|
||||
### 1.4.0 (2013-02-13)
|
||||
|
||||
* Added RedisHandler to log to Redis via the Predis library or the phpredis extension
|
||||
* Added ZendMonitorHandler to log to the Zend Server monitor
|
||||
* Added the possibility to pass arrays of handlers and processors directly in the Logger constructor
|
||||
* Added `$useSSL` option to the PushoverHandler which is enabled by default
|
||||
* Fixed ChromePHPHandler and FirePHPHandler issue when multiple instances are used simultaneously
|
||||
* Fixed header injection capability in the NativeMailHandler
|
||||
|
||||
### 1.3.1 (2013-01-11)
|
||||
|
||||
* Fixed LogstashFormatter to be usable with stream handlers
|
||||
* Fixed GelfMessageFormatter levels on Windows
|
||||
|
||||
### 1.3.0 (2013-01-08)
|
||||
|
||||
* Added PSR-3 compliance, the `Monolog\Logger` class is now an instance of `Psr\Log\LoggerInterface`
|
||||
* Added PsrLogMessageProcessor that you can selectively enable for full PSR-3 compliance
|
||||
* Added LogstashFormatter (combine with SocketHandler or StreamHandler to send logs to Logstash)
|
||||
* Added PushoverHandler to send mobile notifications
|
||||
* Added CouchDBHandler and DoctrineCouchDBHandler
|
||||
* Added RavenHandler to send data to Sentry servers
|
||||
* Added support for the new MongoClient class in MongoDBHandler
|
||||
* Added microsecond precision to log records' timestamps
|
||||
* Added `$flushOnOverflow` param to BufferHandler to flush by batches instead of losing
|
||||
the oldest entries
|
||||
* Fixed normalization of objects with cyclic references
|
||||
|
||||
### 1.2.1 (2012-08-29)
|
||||
|
||||
* Added new $logopts arg to SyslogHandler to provide custom openlog options
|
||||
* Fixed fatal error in SyslogHandler
|
||||
|
||||
### 1.2.0 (2012-08-18)
|
||||
|
||||
* Added AmqpHandler (for use with AMQP servers)
|
||||
* Added CubeHandler
|
||||
* Added NativeMailerHandler::addHeader() to send custom headers in mails
|
||||
* Added the possibility to specify more than one recipient in NativeMailerHandler
|
||||
* Added the possibility to specify float timeouts in SocketHandler
|
||||
* Added NOTICE and EMERGENCY levels to conform with RFC 5424
|
||||
* Fixed the log records to use the php default timezone instead of UTC
|
||||
* Fixed BufferHandler not being flushed properly on PHP fatal errors
|
||||
* Fixed normalization of exotic resource types
|
||||
* Fixed the default format of the SyslogHandler to avoid duplicating datetimes in syslog
|
||||
|
||||
### 1.1.0 (2012-04-23)
|
||||
|
||||
* Added Monolog\Logger::isHandling() to check if a handler will
|
||||
handle the given log level
|
||||
* Added ChromePHPHandler
|
||||
* Added MongoDBHandler
|
||||
* Added GelfHandler (for use with Graylog2 servers)
|
||||
* Added SocketHandler (for use with syslog-ng for example)
|
||||
* Added NormalizerFormatter
|
||||
* Added the possibility to change the activation strategy of the FingersCrossedHandler
|
||||
* Added possibility to show microseconds in logs
|
||||
* Added `server` and `referer` to WebProcessor output
|
||||
|
||||
### 1.0.2 (2011-10-24)
|
||||
|
||||
* Fixed bug in IE with large response headers and FirePHPHandler
|
||||
|
||||
### 1.0.1 (2011-08-25)
|
||||
|
||||
* Added MemoryPeakUsageProcessor and MemoryUsageProcessor
|
||||
* Added Monolog\Logger::getName() to get a logger's channel name
|
||||
|
||||
### 1.0.0 (2011-07-06)
|
||||
|
||||
* Added IntrospectionProcessor to get info from where the logger was called
|
||||
* Fixed WebProcessor in CLI
|
||||
|
||||
### 1.0.0-RC1 (2011-07-01)
|
||||
|
||||
* Initial release
|
||||
19
src/composer/vendor/monolog/monolog/LICENSE
vendored
Normal file
19
src/composer/vendor/monolog/monolog/LICENSE
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2011-2014 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.
|
||||
292
src/composer/vendor/monolog/monolog/README.mdown
vendored
Normal file
292
src/composer/vendor/monolog/monolog/README.mdown
vendored
Normal file
@@ -0,0 +1,292 @@
|
||||
Monolog - Logging for PHP 5.3+ [](http://travis-ci.org/Seldaek/monolog)
|
||||
==============================
|
||||
|
||||
[](https://packagist.org/packages/monolog/monolog)
|
||||
[](https://packagist.org/packages/monolog/monolog)
|
||||
[](https://www.versioneye.com/php/monolog:monolog/references)
|
||||
|
||||
|
||||
Monolog sends your logs to files, sockets, inboxes, databases and various
|
||||
web services. See the complete list of handlers below. Special handlers
|
||||
allow you to build advanced logging strategies.
|
||||
|
||||
This library implements the [PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md)
|
||||
interface that you can type-hint against in your own libraries to keep
|
||||
a maximum of interoperability. You can also use it in your applications to
|
||||
make sure you can always use another compatible logger at a later time.
|
||||
As of 1.11.0 Monolog public APIs will also accept PSR-3 log levels.
|
||||
Internally Monolog still uses its own level scheme since it predates PSR-3.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Install the latest version with `composer require monolog/monolog`
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use Monolog\Logger;
|
||||
use Monolog\Handler\StreamHandler;
|
||||
|
||||
// create a log channel
|
||||
$log = new Logger('name');
|
||||
$log->pushHandler(new StreamHandler('path/to/your.log', Logger::WARNING));
|
||||
|
||||
// add records to the log
|
||||
$log->addWarning('Foo');
|
||||
$log->addError('Bar');
|
||||
```
|
||||
|
||||
Core Concepts
|
||||
-------------
|
||||
|
||||
Every `Logger` instance has a channel (name) and a stack of handlers. Whenever
|
||||
you add a record to the logger, it traverses the handler stack. Each handler
|
||||
decides whether it fully handled the record, and if so, the propagation of the
|
||||
record ends there.
|
||||
|
||||
This allows for flexible logging setups, for example having a `StreamHandler` at
|
||||
the bottom of the stack that will log anything to disk, and on top of that add
|
||||
a `MailHandler` that will send emails only when an error message is logged.
|
||||
Handlers also have a `$bubble` property which defines whether they block the
|
||||
record or not if they handled it. In this example, setting the `MailHandler`'s
|
||||
`$bubble` argument to false means that records handled by the `MailHandler` will
|
||||
not propagate to the `StreamHandler` anymore.
|
||||
|
||||
You can create many `Logger`s, each defining a channel (e.g.: db, request,
|
||||
router, ..) and each of them combining various handlers, which can be shared
|
||||
or not. The channel is reflected in the logs and allows you to easily see or
|
||||
filter records.
|
||||
|
||||
Each Handler also has a Formatter, a default one with settings that make sense
|
||||
will be created if you don't set one. The formatters normalize and format
|
||||
incoming records so that they can be used by the handlers to output useful
|
||||
information.
|
||||
|
||||
Custom severity levels are not available. Only the eight
|
||||
[RFC 5424](http://tools.ietf.org/html/rfc5424) levels (debug, info, notice,
|
||||
warning, error, critical, alert, emergency) are present for basic filtering
|
||||
purposes, but for sorting and other use cases that would require
|
||||
flexibility, you should add Processors to the Logger that can add extra
|
||||
information (tags, user ip, ..) to the records before they are handled.
|
||||
|
||||
Log Levels
|
||||
----------
|
||||
|
||||
Monolog supports the logging levels described by [RFC 5424](http://tools.ietf.org/html/rfc5424).
|
||||
|
||||
- **DEBUG** (100): Detailed debug information.
|
||||
|
||||
- **INFO** (200): Interesting events. Examples: User logs in, SQL logs.
|
||||
|
||||
- **NOTICE** (250): Normal but significant events.
|
||||
|
||||
- **WARNING** (300): Exceptional occurrences that are not errors. Examples:
|
||||
Use of deprecated APIs, poor use of an API, undesirable things that are not
|
||||
necessarily wrong.
|
||||
|
||||
- **ERROR** (400): Runtime errors that do not require immediate action but
|
||||
should typically be logged and monitored.
|
||||
|
||||
- **CRITICAL** (500): Critical conditions. Example: Application component
|
||||
unavailable, unexpected exception.
|
||||
|
||||
- **ALERT** (550): Action must be taken immediately. Example: Entire website
|
||||
down, database unavailable, etc. This should trigger the SMS alerts and wake
|
||||
you up.
|
||||
|
||||
- **EMERGENCY** (600): Emergency: system is unusable.
|
||||
|
||||
Docs
|
||||
====
|
||||
|
||||
**See the `doc` directory for more detailed documentation.
|
||||
The following is only a list of all parts that come with Monolog.**
|
||||
|
||||
Handlers
|
||||
--------
|
||||
|
||||
### Log to files and syslog
|
||||
|
||||
- _StreamHandler_: Logs records into any PHP stream, use this for log files.
|
||||
- _RotatingFileHandler_: Logs records to a file and creates one logfile per day.
|
||||
It will also delete files older than `$maxFiles`. You should use
|
||||
[logrotate](http://linuxcommand.org/man_pages/logrotate8.html) for high profile
|
||||
setups though, this is just meant as a quick and dirty solution.
|
||||
- _SyslogHandler_: Logs records to the syslog.
|
||||
- _ErrorLogHandler_: Logs records to PHP's
|
||||
[`error_log()`](http://docs.php.net/manual/en/function.error-log.php) function.
|
||||
|
||||
### Send alerts and emails
|
||||
|
||||
- _NativeMailerHandler_: Sends emails using PHP's
|
||||
[`mail()`](http://php.net/manual/en/function.mail.php) function.
|
||||
- _SwiftMailerHandler_: Sends emails using a [`Swift_Mailer`](http://swiftmailer.org/) instance.
|
||||
- _PushoverHandler_: Sends mobile notifications via the [Pushover](https://www.pushover.net/) API.
|
||||
- _HipChatHandler_: Logs records to a [HipChat](http://hipchat.com) chat room using its API.
|
||||
- _FlowdockHandler_: Logs records to a [Flowdock](https://www.flowdock.com/) account.
|
||||
- _SlackHandler_: Logs records to a [Slack](https://www.slack.com/) account.
|
||||
- _MandrillHandler_: Sends emails via the Mandrill API using a [`Swift_Message`](http://swiftmailer.org/) instance.
|
||||
- _FleepHookHandler_: Logs records to a [Fleep](https://fleep.io/) conversation using Webhooks.
|
||||
|
||||
### Log specific servers and networked logging
|
||||
|
||||
- _SocketHandler_: Logs records to [sockets](http://php.net/fsockopen), use this
|
||||
for UNIX and TCP sockets. See an [example](https://github.com/Seldaek/monolog/blob/master/doc/sockets.md).
|
||||
- _AmqpHandler_: Logs records to an [amqp](http://www.amqp.org/) compatible
|
||||
server. Requires the [php-amqp](http://pecl.php.net/package/amqp) extension (1.0+).
|
||||
- _GelfHandler_: Logs records to a [Graylog2](http://www.graylog2.org) server.
|
||||
- _CubeHandler_: Logs records to a [Cube](http://square.github.com/cube/) server.
|
||||
- _RavenHandler_: Logs records to a [Sentry](http://getsentry.com/) server using
|
||||
[raven](https://packagist.org/packages/raven/raven).
|
||||
- _ZendMonitorHandler_: Logs records to the Zend Monitor present in Zend Server.
|
||||
- _NewRelicHandler_: Logs records to a [NewRelic](http://newrelic.com/) application.
|
||||
- _LogglyHandler_: Logs records to a [Loggly](http://www.loggly.com/) account.
|
||||
- _RollbarHandler_: Logs records to a [Rollbar](https://rollbar.com/) account.
|
||||
- _SyslogUdpHandler_: Logs records to a remote [Syslogd](http://www.rsyslog.com/) server.
|
||||
- _LogEntriesHandler_: Logs records to a [LogEntries](http://logentries.com/) account.
|
||||
|
||||
### Logging in development
|
||||
|
||||
- _FirePHPHandler_: Handler for [FirePHP](http://www.firephp.org/), providing
|
||||
inline `console` messages within [FireBug](http://getfirebug.com/).
|
||||
- _ChromePHPHandler_: Handler for [ChromePHP](http://www.chromephp.com/), providing
|
||||
inline `console` messages within Chrome.
|
||||
- _BrowserConsoleHandler_: Handler to send logs to browser's Javascript `console` with
|
||||
no browser extension required. Most browsers supporting `console` API are supported.
|
||||
|
||||
### Log to databases
|
||||
|
||||
- _RedisHandler_: Logs records to a [redis](http://redis.io) server.
|
||||
- _MongoDBHandler_: Handler to write records in MongoDB via a
|
||||
[Mongo](http://pecl.php.net/package/mongo) extension connection.
|
||||
- _CouchDBHandler_: Logs records to a CouchDB server.
|
||||
- _DoctrineCouchDBHandler_: Logs records to a CouchDB server via the Doctrine CouchDB ODM.
|
||||
- _ElasticSearchHandler_: Logs records to an Elastic Search server.
|
||||
- _DynamoDbHandler_: Logs records to a DynamoDB table with the [AWS SDK](https://github.com/aws/aws-sdk-php).
|
||||
|
||||
### Wrappers / Special Handlers
|
||||
|
||||
- _FingersCrossedHandler_: A very interesting wrapper. It takes a logger as
|
||||
parameter and will accumulate log records of all levels until a record
|
||||
exceeds the defined severity level. At which point it delivers all records,
|
||||
including those of lower severity, to the handler it wraps. This means that
|
||||
until an error actually happens you will not see anything in your logs, but
|
||||
when it happens you will have the full information, including debug and info
|
||||
records. This provides you with all the information you need, but only when
|
||||
you need it.
|
||||
- _WhatFailureGroupHandler_: This handler extends the _GroupHandler_ ignoring
|
||||
exceptions raised by each child handler. This allows you to ignore issues
|
||||
where a remote tcp connection may have died but you do not want your entire
|
||||
application to crash and may wish to continue to log to other handlers.
|
||||
- _BufferHandler_: This handler will buffer all the log records it receives
|
||||
until `close()` is called at which point it will call `handleBatch()` on the
|
||||
handler it wraps with all the log messages at once. This is very useful to
|
||||
send an email with all records at once for example instead of having one mail
|
||||
for every log record.
|
||||
- _GroupHandler_: This handler groups other handlers. Every record received is
|
||||
sent to all the handlers it is configured with.
|
||||
- _FilterHandler_: This handler only lets records of the given levels through
|
||||
to the wrapped handler.
|
||||
- _SamplingHandler_: Wraps around another handler and lets you sample records
|
||||
if you only want to store some of them.
|
||||
- _NullHandler_: Any record it can handle will be thrown away. This can be used
|
||||
to put on top of an existing handler stack to disable it temporarily.
|
||||
- _PsrHandler_: Can be used to forward log records to an existing PSR-3 logger
|
||||
- _TestHandler_: Used for testing, it records everything that is sent to it and
|
||||
has accessors to read out the information.
|
||||
|
||||
Formatters
|
||||
----------
|
||||
|
||||
- _LineFormatter_: Formats a log record into a one-line string.
|
||||
- _HtmlFormatter_: Used to format log records into a human readable html table, mainly suitable for emails.
|
||||
- _NormalizerFormatter_: Normalizes objects/resources down to strings so a record can easily be serialized/encoded.
|
||||
- _ScalarFormatter_: Used to format log records into an associative array of scalar values.
|
||||
- _JsonFormatter_: Encodes a log record into json.
|
||||
- _WildfireFormatter_: Used to format log records into the Wildfire/FirePHP protocol, only useful for the FirePHPHandler.
|
||||
- _ChromePHPFormatter_: Used to format log records into the ChromePHP format, only useful for the ChromePHPHandler.
|
||||
- _GelfMessageFormatter_: Used to format log records into Gelf message instances, only useful for the GelfHandler.
|
||||
- _LogstashFormatter_: Used to format log records into [logstash](http://logstash.net/) event json, useful for any handler listed under inputs [here](http://logstash.net/docs/latest).
|
||||
- _ElasticaFormatter_: Used to format log records into an Elastica\Document object, only useful for the ElasticSearchHandler.
|
||||
- _LogglyFormatter_: Used to format log records into Loggly messages, only useful for the LogglyHandler.
|
||||
- _FlowdockFormatter_: Used to format log records into Flowdock messages, only useful for the FlowdockHandler.
|
||||
- _MongoDBFormatter_: Converts \DateTime instances to \MongoDate and objects recursively to arrays, only useful with the MongoDBHandler.
|
||||
|
||||
Processors
|
||||
----------
|
||||
|
||||
- _IntrospectionProcessor_: Adds the line/file/class/method from which the log call originated.
|
||||
- _WebProcessor_: Adds the current request URI, request method and client IP to a log record.
|
||||
- _MemoryUsageProcessor_: Adds the current memory usage to a log record.
|
||||
- _MemoryPeakUsageProcessor_: Adds the peak memory usage to a log record.
|
||||
- _ProcessIdProcessor_: Adds the process id to a log record.
|
||||
- _UidProcessor_: Adds a unique identifier to a log record.
|
||||
- _GitProcessor_: Adds the current git branch and commit to a log record.
|
||||
- _TagProcessor_: Adds an array of predefined tags to a log record.
|
||||
|
||||
Utilities
|
||||
---------
|
||||
|
||||
- _Registry_: The `Monolog\Registry` class lets you configure global loggers that you
|
||||
can then statically access from anywhere. It is not really a best practice but can
|
||||
help in some older codebases or for ease of use.
|
||||
- _ErrorHandler_: The `Monolog\ErrorHandler` class allows you to easily register
|
||||
a Logger instance as an exception handler, error handler or fatal error handler.
|
||||
- _ErrorLevelActivationStrategy_: Activates a FingersCrossedHandler when a certain log
|
||||
level is reached.
|
||||
- _ChannelLevelActivationStrategy_: Activates a FingersCrossedHandler when a certain
|
||||
log level is reached, depending on which channel received the log record.
|
||||
|
||||
Third Party Packages
|
||||
--------------------
|
||||
|
||||
Third party handlers, formatters and processors are
|
||||
[listed in the wiki](https://github.com/Seldaek/monolog/wiki/Third-Party-Packages). You
|
||||
can also add your own there if you publish one.
|
||||
|
||||
About
|
||||
=====
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
- Monolog works with PHP 5.3 or above, and is also tested to work with HHVM.
|
||||
|
||||
Submitting bugs and feature requests
|
||||
------------------------------------
|
||||
|
||||
Bugs and feature request are tracked on [GitHub](https://github.com/Seldaek/monolog/issues)
|
||||
|
||||
Frameworks Integration
|
||||
----------------------
|
||||
|
||||
- Frameworks and libraries using [PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md)
|
||||
can be used very easily with Monolog since it implements the interface.
|
||||
- [Symfony2](http://symfony.com) comes out of the box with Monolog.
|
||||
- [Silex](http://silex.sensiolabs.org/) comes out of the box with Monolog.
|
||||
- [Laravel 4 & 5](http://laravel.com/) come out of the box with Monolog.
|
||||
- [PPI](http://www.ppi.io/) comes out of the box with Monolog.
|
||||
- [CakePHP](http://cakephp.org/) is usable with Monolog via the [cakephp-monolog](https://github.com/jadb/cakephp-monolog) plugin.
|
||||
- [Slim](http://www.slimframework.com/) is usable with Monolog via the [Slim-Monolog](https://github.com/Flynsarmy/Slim-Monolog) log writer.
|
||||
- [XOOPS 2.6](http://xoops.org/) comes out of the box with Monolog.
|
||||
- [Aura.Web_Project](https://github.com/auraphp/Aura.Web_Project) comes out of the box with Monolog.
|
||||
- [Nette Framework](http://nette.org/en/) can be used with Monolog via [Kdyby/Monolog](https://github.com/Kdyby/Monolog) extension.
|
||||
- [Proton Micro Framework](https://github.com/alexbilbie/Proton) comes out of the box with Monolog.
|
||||
|
||||
Author
|
||||
------
|
||||
|
||||
Jordi Boggiano - <j.boggiano@seld.be> - <http://twitter.com/seldaek><br />
|
||||
See also the list of [contributors](https://github.com/Seldaek/monolog/contributors) which participated in this project.
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
Monolog is licensed under the MIT License - see the `LICENSE` file for details
|
||||
|
||||
Acknowledgements
|
||||
----------------
|
||||
|
||||
This library is heavily inspired by Python's [Logbook](http://packages.python.org/Logbook/)
|
||||
library, although most concepts have been adjusted to fit to the PHP world.
|
||||
54
src/composer/vendor/monolog/monolog/composer.json
vendored
Normal file
54
src/composer/vendor/monolog/monolog/composer.json
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"name": "monolog/monolog",
|
||||
"description": "Sends your logs to files, sockets, inboxes, databases and various web services",
|
||||
"keywords": ["log", "logging", "psr-3"],
|
||||
"homepage": "http://github.com/Seldaek/monolog",
|
||||
"type": "library",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jordi Boggiano",
|
||||
"email": "j.boggiano@seld.be",
|
||||
"homepage": "http://seld.be"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.3.0",
|
||||
"psr/log": "~1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.0",
|
||||
"graylog2/gelf-php": "~1.0",
|
||||
"raven/raven": "~0.5",
|
||||
"ruflin/elastica": "0.90.*",
|
||||
"doctrine/couchdb": "~1.0@dev",
|
||||
"aws/aws-sdk-php": "~2.4, >2.4.8",
|
||||
"videlalvaro/php-amqplib": "~2.4",
|
||||
"swiftmailer/swiftmailer": "~5.3"
|
||||
},
|
||||
"suggest": {
|
||||
"graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
|
||||
"raven/raven": "Allow sending log messages to a Sentry server",
|
||||
"doctrine/couchdb": "Allow sending log messages to a CouchDB server",
|
||||
"ruflin/elastica": "Allow sending log messages to an Elastic Search server",
|
||||
"videlalvaro/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib",
|
||||
"ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
|
||||
"ext-mongo": "Allow sending log messages to a MongoDB server",
|
||||
"aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
|
||||
"rollbar/rollbar": "Allow sending log messages to Rollbar"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {"Monolog\\": "src/Monolog"}
|
||||
},
|
||||
"provide": {
|
||||
"psr/log-implementation": "1.0.0"
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.13.x-dev"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"test": "phpunit"
|
||||
}
|
||||
}
|
||||
76
src/composer/vendor/monolog/monolog/doc/extending.md
vendored
Normal file
76
src/composer/vendor/monolog/monolog/doc/extending.md
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
Extending Monolog
|
||||
=================
|
||||
|
||||
Monolog is fully extensible, allowing you to adapt your logger to your needs.
|
||||
|
||||
Writing your own handler
|
||||
------------------------
|
||||
|
||||
Monolog provides many built-in handlers. But if the one you need does not
|
||||
exist, you can write it and use it in your logger. The only requirement is
|
||||
to implement `Monolog\Handler\HandlerInterface`.
|
||||
|
||||
Let's write a PDOHandler to log records to a database. We will extend the
|
||||
abstract class provided by Monolog to keep things DRY.
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use Monolog\Logger;
|
||||
use Monolog\Handler\AbstractProcessingHandler;
|
||||
|
||||
class PDOHandler extends AbstractProcessingHandler
|
||||
{
|
||||
private $initialized = false;
|
||||
private $pdo;
|
||||
private $statement;
|
||||
|
||||
public function __construct(PDO $pdo, $level = Logger::DEBUG, $bubble = true)
|
||||
{
|
||||
$this->pdo = $pdo;
|
||||
parent::__construct($level, $bubble);
|
||||
}
|
||||
|
||||
protected function write(array $record)
|
||||
{
|
||||
if (!$this->initialized) {
|
||||
$this->initialize();
|
||||
}
|
||||
|
||||
$this->statement->execute(array(
|
||||
'channel' => $record['channel'],
|
||||
'level' => $record['level'],
|
||||
'message' => $record['formatted'],
|
||||
'time' => $record['datetime']->format('U'),
|
||||
));
|
||||
}
|
||||
|
||||
private function initialize()
|
||||
{
|
||||
$this->pdo->exec(
|
||||
'CREATE TABLE IF NOT EXISTS monolog '
|
||||
.'(channel VARCHAR(255), level INTEGER, message LONGTEXT, time INTEGER UNSIGNED)'
|
||||
);
|
||||
$this->statement = $this->pdo->prepare(
|
||||
'INSERT INTO monolog (channel, level, message, time) VALUES (:channel, :level, :message, :time)'
|
||||
);
|
||||
|
||||
$this->initialized = true;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can now use this handler in your logger:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
$logger->pushHandler(new PDOHandler(new PDO('sqlite:logs.sqlite')));
|
||||
|
||||
// You can now use your logger
|
||||
$logger->addInfo('My logger is now ready');
|
||||
```
|
||||
|
||||
The `Monolog\Handler\AbstractProcessingHandler` class provides most of the
|
||||
logic needed for the handler, including the use of processors and the formatting
|
||||
of the record (which is why we use ``$record['formatted']`` instead of ``$record['message']``).
|
||||
37
src/composer/vendor/monolog/monolog/doc/sockets.md
vendored
Normal file
37
src/composer/vendor/monolog/monolog/doc/sockets.md
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
Sockets Handler
|
||||
===============
|
||||
|
||||
This handler allows you to write your logs to sockets using [fsockopen](http://php.net/fsockopen)
|
||||
or [pfsockopen](http://php.net/pfsockopen).
|
||||
|
||||
Persistent sockets are mainly useful in web environments where you gain some performance not closing/opening
|
||||
the connections between requests.
|
||||
|
||||
Basic Example
|
||||
-------------
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use Monolog\Logger;
|
||||
use Monolog\Handler\SocketHandler;
|
||||
|
||||
// Create the logger
|
||||
$logger = new Logger('my_logger');
|
||||
|
||||
// Create the handler
|
||||
$handler = new SocketHandler('unix:///var/log/httpd_app_log.socket');
|
||||
$handler->setPersistent(true);
|
||||
|
||||
// Now add the handler
|
||||
$logger->pushHandler($handler, Logger::DEBUG);
|
||||
|
||||
// You can now use your logger
|
||||
$logger->addInfo('My logger is now ready');
|
||||
|
||||
```
|
||||
|
||||
In this example, using syslog-ng, you should see the log on the log server:
|
||||
|
||||
cweb1 [2012-02-26 00:12:03] my_logger.INFO: My logger is now ready [] []
|
||||
|
||||
162
src/composer/vendor/monolog/monolog/doc/usage.md
vendored
Normal file
162
src/composer/vendor/monolog/monolog/doc/usage.md
vendored
Normal file
@@ -0,0 +1,162 @@
|
||||
Using Monolog
|
||||
=============
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
Monolog is available on Packagist ([monolog/monolog](http://packagist.org/packages/monolog/monolog))
|
||||
and as such installable via [Composer](http://getcomposer.org/).
|
||||
|
||||
```bash
|
||||
php composer.phar require monolog/monolog
|
||||
```
|
||||
|
||||
If you do not use Composer, you can grab the code from GitHub, and use any
|
||||
PSR-0 compatible autoloader (e.g. the [Symfony2 ClassLoader component](https://github.com/symfony/ClassLoader))
|
||||
to load Monolog classes.
|
||||
|
||||
Configuring a logger
|
||||
--------------------
|
||||
|
||||
Here is a basic setup to log to a file and to firephp on the DEBUG level:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use Monolog\Logger;
|
||||
use Monolog\Handler\StreamHandler;
|
||||
use Monolog\Handler\FirePHPHandler;
|
||||
|
||||
// Create the logger
|
||||
$logger = new Logger('my_logger');
|
||||
// Now add some handlers
|
||||
$logger->pushHandler(new StreamHandler(__DIR__.'/my_app.log', Logger::DEBUG));
|
||||
$logger->pushHandler(new FirePHPHandler());
|
||||
|
||||
// You can now use your logger
|
||||
$logger->addInfo('My logger is now ready');
|
||||
```
|
||||
|
||||
Let's explain it. The first step is to create the logger instance which will
|
||||
be used in your code. The argument is a channel name, which is useful when
|
||||
you use several loggers (see below for more details about it).
|
||||
|
||||
The logger itself does not know how to handle a record. It delegates it to
|
||||
some handlers. The code above registers two handlers in the stack to allow
|
||||
handling records in two different ways.
|
||||
|
||||
Note that the FirePHPHandler is called first as it is added on top of the
|
||||
stack. This allows you to temporarily add a logger with bubbling disabled if
|
||||
you want to override other configured loggers.
|
||||
|
||||
Adding extra data in the records
|
||||
--------------------------------
|
||||
|
||||
Monolog provides two different ways to add extra informations along the simple
|
||||
textual message.
|
||||
|
||||
### Using the logging context
|
||||
|
||||
The first way is the context, allowing to pass an array of data along the
|
||||
record:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
$logger->addInfo('Adding a new user', array('username' => 'Seldaek'));
|
||||
```
|
||||
|
||||
Simple handlers (like the StreamHandler for instance) will simply format
|
||||
the array to a string but richer handlers can take advantage of the context
|
||||
(FirePHP is able to display arrays in pretty way for instance).
|
||||
|
||||
### Using processors
|
||||
|
||||
The second way is to add extra data for all records by using a processor.
|
||||
Processors can be any callable. They will get the record as parameter and
|
||||
must return it after having eventually changed the `extra` part of it. Let's
|
||||
write a processor adding some dummy data in the record:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
$logger->pushProcessor(function ($record) {
|
||||
$record['extra']['dummy'] = 'Hello world!';
|
||||
|
||||
return $record;
|
||||
});
|
||||
```
|
||||
|
||||
Monolog provides some built-in processors that can be used in your project.
|
||||
Look at the [README file](https://github.com/Seldaek/monolog/blob/master/README.mdown) for the list.
|
||||
|
||||
> Tip: processors can also be registered on a specific handler instead of
|
||||
the logger to apply only for this handler.
|
||||
|
||||
Leveraging channels
|
||||
-------------------
|
||||
|
||||
Channels are a great way to identify to which part of the application a record
|
||||
is related. This is useful in big applications (and is leveraged by
|
||||
MonologBundle in Symfony2).
|
||||
|
||||
Picture two loggers sharing a handler that writes to a single log file.
|
||||
Channels would allow you to identify the logger that issued every record.
|
||||
You can easily grep through the log files filtering this or that channel.
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use Monolog\Logger;
|
||||
use Monolog\Handler\StreamHandler;
|
||||
use Monolog\Handler\FirePHPHandler;
|
||||
|
||||
// Create some handlers
|
||||
$stream = new StreamHandler(__DIR__.'/my_app.log', Logger::DEBUG);
|
||||
$firephp = new FirePHPHandler();
|
||||
|
||||
// Create the main logger of the app
|
||||
$logger = new Logger('my_logger');
|
||||
$logger->pushHandler($stream);
|
||||
$logger->pushHandler($firephp);
|
||||
|
||||
// Create a logger for the security-related stuff with a different channel
|
||||
$securityLogger = new Logger('security');
|
||||
$securityLogger->pushHandler($stream);
|
||||
$securityLogger->pushHandler($firephp);
|
||||
```
|
||||
|
||||
Customizing log format
|
||||
----------------------
|
||||
|
||||
In Monolog it's easy to customize the format of the logs written into files,
|
||||
sockets, mails, databases and other handlers. Most of the handlers use the
|
||||
|
||||
```php
|
||||
$record['formatted']
|
||||
```
|
||||
|
||||
value to be automatically put into the log device. This value depends on the
|
||||
formatter settings. You can choose between predefined formatter classes or
|
||||
write your own (e.g. a multiline text file for human-readable output).
|
||||
|
||||
To configure a predefined formatter class, just set it as the handler's field:
|
||||
|
||||
```php
|
||||
// the default date format is "Y-m-d H:i:s"
|
||||
$dateFormat = "Y n j, g:i a";
|
||||
// the default output format is "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n"
|
||||
$output = "%datetime% > %level_name% > %message% %context% %extra%\n";
|
||||
// finally, create a formatter
|
||||
$formatter = new LineFormatter($output, $dateFormat);
|
||||
|
||||
// Create a handler
|
||||
$stream = new StreamHandler(__DIR__.'/my_app.log', Logger::DEBUG);
|
||||
$stream->setFormatter($formatter);
|
||||
// bind it to a logger object
|
||||
$securityLogger = new Logger('security');
|
||||
$securityLogger->pushHandler($stream);
|
||||
```
|
||||
|
||||
You may also reuse the same formatter between multiple handlers and share those
|
||||
handlers between multiple loggers.
|
||||
15
src/composer/vendor/monolog/monolog/phpunit.xml.dist
vendored
Normal file
15
src/composer/vendor/monolog/monolog/phpunit.xml.dist
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<phpunit bootstrap="tests/bootstrap.php" colors="true">
|
||||
<testsuites>
|
||||
<testsuite name="Monolog Test Suite">
|
||||
<directory>tests/Monolog/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory suffix=".php">src/Monolog/</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
</phpunit>
|
||||
208
src/composer/vendor/monolog/monolog/src/Monolog/ErrorHandler.php
vendored
Normal file
208
src/composer/vendor/monolog/monolog/src/Monolog/ErrorHandler.php
vendored
Normal file
@@ -0,0 +1,208 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Monolog package.
|
||||
*
|
||||
* (c) 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 Monolog;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Psr\Log\LogLevel;
|
||||
|
||||
/**
|
||||
* Monolog error handler
|
||||
*
|
||||
* A facility to enable logging of runtime errors, exceptions and fatal errors.
|
||||
*
|
||||
* Quick setup: <code>ErrorHandler::register($logger);</code>
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*/
|
||||
class ErrorHandler
|
||||
{
|
||||
private $logger;
|
||||
|
||||
private $previousExceptionHandler;
|
||||
private $uncaughtExceptionLevel;
|
||||
|
||||
private $previousErrorHandler;
|
||||
private $errorLevelMap;
|
||||
|
||||
private $fatalLevel;
|
||||
private $reservedMemory;
|
||||
private static $fatalErrors = array(E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR);
|
||||
|
||||
public function __construct(LoggerInterface $logger)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a new ErrorHandler for a given Logger
|
||||
*
|
||||
* By default it will handle errors, exceptions and fatal errors
|
||||
*
|
||||
* @param LoggerInterface $logger
|
||||
* @param array|false $errorLevelMap an array of E_* constant to LogLevel::* constant mapping, or false to disable error handling
|
||||
* @param int|false $exceptionLevel a LogLevel::* constant, or false to disable exception handling
|
||||
* @param int|false $fatalLevel a LogLevel::* constant, or false to disable fatal error handling
|
||||
* @return ErrorHandler
|
||||
*/
|
||||
public static function register(LoggerInterface $logger, $errorLevelMap = array(), $exceptionLevel = null, $fatalLevel = null)
|
||||
{
|
||||
$handler = new static($logger);
|
||||
if ($errorLevelMap !== false) {
|
||||
$handler->registerErrorHandler($errorLevelMap);
|
||||
}
|
||||
if ($exceptionLevel !== false) {
|
||||
$handler->registerExceptionHandler($exceptionLevel);
|
||||
}
|
||||
if ($fatalLevel !== false) {
|
||||
$handler->registerFatalHandler($fatalLevel);
|
||||
}
|
||||
|
||||
return $handler;
|
||||
}
|
||||
|
||||
public function registerExceptionHandler($level = null, $callPrevious = true)
|
||||
{
|
||||
$prev = set_exception_handler(array($this, 'handleException'));
|
||||
$this->uncaughtExceptionLevel = $level;
|
||||
if ($callPrevious && $prev) {
|
||||
$this->previousExceptionHandler = $prev;
|
||||
}
|
||||
}
|
||||
|
||||
public function registerErrorHandler(array $levelMap = array(), $callPrevious = true, $errorTypes = -1)
|
||||
{
|
||||
$prev = set_error_handler(array($this, 'handleError'), $errorTypes);
|
||||
$this->errorLevelMap = array_replace($this->defaultErrorLevelMap(), $levelMap);
|
||||
if ($callPrevious) {
|
||||
$this->previousErrorHandler = $prev ?: true;
|
||||
}
|
||||
}
|
||||
|
||||
public function registerFatalHandler($level = null, $reservedMemorySize = 20)
|
||||
{
|
||||
register_shutdown_function(array($this, 'handleFatalError'));
|
||||
|
||||
$this->reservedMemory = str_repeat(' ', 1024 * $reservedMemorySize);
|
||||
$this->fatalLevel = $level;
|
||||
}
|
||||
|
||||
protected function defaultErrorLevelMap()
|
||||
{
|
||||
return array(
|
||||
E_ERROR => LogLevel::CRITICAL,
|
||||
E_WARNING => LogLevel::WARNING,
|
||||
E_PARSE => LogLevel::ALERT,
|
||||
E_NOTICE => LogLevel::NOTICE,
|
||||
E_CORE_ERROR => LogLevel::CRITICAL,
|
||||
E_CORE_WARNING => LogLevel::WARNING,
|
||||
E_COMPILE_ERROR => LogLevel::ALERT,
|
||||
E_COMPILE_WARNING => LogLevel::WARNING,
|
||||
E_USER_ERROR => LogLevel::ERROR,
|
||||
E_USER_WARNING => LogLevel::WARNING,
|
||||
E_USER_NOTICE => LogLevel::NOTICE,
|
||||
E_STRICT => LogLevel::NOTICE,
|
||||
E_RECOVERABLE_ERROR => LogLevel::ERROR,
|
||||
E_DEPRECATED => LogLevel::NOTICE,
|
||||
E_USER_DEPRECATED => LogLevel::NOTICE,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
public function handleException(\Exception $e)
|
||||
{
|
||||
$this->logger->log(
|
||||
$this->uncaughtExceptionLevel === null ? LogLevel::ERROR : $this->uncaughtExceptionLevel,
|
||||
sprintf('Uncaught Exception %s: "%s" at %s line %s', get_class($e), $e->getMessage(), $e->getFile(), $e->getLine()),
|
||||
array('exception' => $e)
|
||||
);
|
||||
|
||||
if ($this->previousExceptionHandler) {
|
||||
call_user_func($this->previousExceptionHandler, $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
public function handleError($code, $message, $file = '', $line = 0, $context = array())
|
||||
{
|
||||
if (!(error_reporting() & $code)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$level = isset($this->errorLevelMap[$code]) ? $this->errorLevelMap[$code] : LogLevel::CRITICAL;
|
||||
$this->logger->log($level, self::codeToString($code).': '.$message, array('code' => $code, 'message' => $message, 'file' => $file, 'line' => $line));
|
||||
|
||||
if ($this->previousErrorHandler === true) {
|
||||
return false;
|
||||
} elseif ($this->previousErrorHandler) {
|
||||
return call_user_func($this->previousErrorHandler, $code, $message, $file, $line, $context);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
public function handleFatalError()
|
||||
{
|
||||
$this->reservedMemory = null;
|
||||
|
||||
$lastError = error_get_last();
|
||||
if ($lastError && in_array($lastError['type'], self::$fatalErrors)) {
|
||||
$this->logger->log(
|
||||
$this->fatalLevel === null ? LogLevel::ALERT : $this->fatalLevel,
|
||||
'Fatal Error ('.self::codeToString($lastError['type']).'): '.$lastError['message'],
|
||||
array('code' => $lastError['type'], 'message' => $lastError['message'], 'file' => $lastError['file'], 'line' => $lastError['line'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private static function codeToString($code)
|
||||
{
|
||||
switch ($code) {
|
||||
case E_ERROR:
|
||||
return 'E_ERROR';
|
||||
case E_WARNING:
|
||||
return 'E_WARNING';
|
||||
case E_PARSE:
|
||||
return 'E_PARSE';
|
||||
case E_NOTICE:
|
||||
return 'E_NOTICE';
|
||||
case E_CORE_ERROR:
|
||||
return 'E_CORE_ERROR';
|
||||
case E_CORE_WARNING:
|
||||
return 'E_CORE_WARNING';
|
||||
case E_COMPILE_ERROR:
|
||||
return 'E_COMPILE_ERROR';
|
||||
case E_COMPILE_WARNING:
|
||||
return 'E_COMPILE_WARNING';
|
||||
case E_USER_ERROR:
|
||||
return 'E_USER_ERROR';
|
||||
case E_USER_WARNING:
|
||||
return 'E_USER_WARNING';
|
||||
case E_USER_NOTICE:
|
||||
return 'E_USER_NOTICE';
|
||||
case E_STRICT:
|
||||
return 'E_STRICT';
|
||||
case E_RECOVERABLE_ERROR:
|
||||
return 'E_RECOVERABLE_ERROR';
|
||||
case E_DEPRECATED:
|
||||
return 'E_DEPRECATED';
|
||||
case E_USER_DEPRECATED:
|
||||
return 'E_USER_DEPRECATED';
|
||||
}
|
||||
|
||||
return 'Unknown PHP error';
|
||||
}
|
||||
}
|
||||
79
src/composer/vendor/monolog/monolog/src/Monolog/Formatter/ChromePHPFormatter.php
vendored
Normal file
79
src/composer/vendor/monolog/monolog/src/Monolog/Formatter/ChromePHPFormatter.php
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Monolog package.
|
||||
*
|
||||
* (c) 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 Monolog\Formatter;
|
||||
|
||||
use Monolog\Logger;
|
||||
|
||||
/**
|
||||
* Formats a log message according to the ChromePHP array format
|
||||
*
|
||||
* @author Christophe Coevoet <stof@notk.org>
|
||||
*/
|
||||
class ChromePHPFormatter implements FormatterInterface
|
||||
{
|
||||
/**
|
||||
* Translates Monolog log levels to Wildfire levels.
|
||||
*/
|
||||
private $logLevels = array(
|
||||
Logger::DEBUG => 'log',
|
||||
Logger::INFO => 'info',
|
||||
Logger::NOTICE => 'info',
|
||||
Logger::WARNING => 'warn',
|
||||
Logger::ERROR => 'error',
|
||||
Logger::CRITICAL => 'error',
|
||||
Logger::ALERT => 'error',
|
||||
Logger::EMERGENCY => 'error',
|
||||
);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function format(array $record)
|
||||
{
|
||||
// Retrieve the line and file if set and remove them from the formatted extra
|
||||
$backtrace = 'unknown';
|
||||
if (isset($record['extra']['file']) && isset($record['extra']['line'])) {
|
||||
$backtrace = $record['extra']['file'].' : '.$record['extra']['line'];
|
||||
unset($record['extra']['file']);
|
||||
unset($record['extra']['line']);
|
||||
}
|
||||
|
||||
$message = array('message' => $record['message']);
|
||||
if ($record['context']) {
|
||||
$message['context'] = $record['context'];
|
||||
}
|
||||
if ($record['extra']) {
|
||||
$message['extra'] = $record['extra'];
|
||||
}
|
||||
if (count($message) === 1) {
|
||||
$message = reset($message);
|
||||
}
|
||||
|
||||
return array(
|
||||
$record['channel'],
|
||||
$message,
|
||||
$backtrace,
|
||||
$this->logLevels[$record['level']],
|
||||
);
|
||||
}
|
||||
|
||||
public function formatBatch(array $records)
|
||||
{
|
||||
$formatted = array();
|
||||
|
||||
foreach ($records as $record) {
|
||||
$formatted[] = $this->format($record);
|
||||
}
|
||||
|
||||
return $formatted;
|
||||
}
|
||||
}
|
||||
87
src/composer/vendor/monolog/monolog/src/Monolog/Formatter/ElasticaFormatter.php
vendored
Normal file
87
src/composer/vendor/monolog/monolog/src/Monolog/Formatter/ElasticaFormatter.php
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Monolog package.
|
||||
*
|
||||
* (c) 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 Monolog\Formatter;
|
||||
|
||||
use Elastica\Document;
|
||||
|
||||
/**
|
||||
* Format a log message into an Elastica Document
|
||||
*
|
||||
* @author Jelle Vink <jelle.vink@gmail.com>
|
||||
*/
|
||||
class ElasticaFormatter extends NormalizerFormatter
|
||||
{
|
||||
/**
|
||||
* @var string Elastic search index name
|
||||
*/
|
||||
protected $index;
|
||||
|
||||
/**
|
||||
* @var string Elastic search document type
|
||||
*/
|
||||
protected $type;
|
||||
|
||||
/**
|
||||
* @param string $index Elastic Search index name
|
||||
* @param string $type Elastic Search document type
|
||||
*/
|
||||
public function __construct($index, $type)
|
||||
{
|
||||
parent::__construct(\DateTime::ISO8601);
|
||||
$this->index = $index;
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function format(array $record)
|
||||
{
|
||||
$record = parent::format($record);
|
||||
|
||||
return $this->getDocument($record);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter index
|
||||
* @return string
|
||||
*/
|
||||
public function getIndex()
|
||||
{
|
||||
return $this->index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter type
|
||||
* @return string
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a log message into an Elastica Document
|
||||
*
|
||||
* @param array $record Log message
|
||||
* @return Document
|
||||
*/
|
||||
protected function getDocument($record)
|
||||
{
|
||||
$document = new Document();
|
||||
$document->setData($record);
|
||||
$document->setType($this->type);
|
||||
$document->setIndex($this->index);
|
||||
|
||||
return $document;
|
||||
}
|
||||
}
|
||||
104
src/composer/vendor/monolog/monolog/src/Monolog/Formatter/FlowdockFormatter.php
vendored
Normal file
104
src/composer/vendor/monolog/monolog/src/Monolog/Formatter/FlowdockFormatter.php
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Monolog package.
|
||||
*
|
||||
* (c) 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 Monolog\Formatter;
|
||||
|
||||
/**
|
||||
* formats the record to be used in the FlowdockHandler
|
||||
*
|
||||
* @author Dominik Liebler <liebler.dominik@gmail.com>
|
||||
*/
|
||||
class FlowdockFormatter implements FormatterInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $source;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sourceEmail;
|
||||
|
||||
/**
|
||||
* @param string $source
|
||||
* @param string $sourceEmail
|
||||
*/
|
||||
public function __construct($source, $sourceEmail)
|
||||
{
|
||||
$this->source = $source;
|
||||
$this->sourceEmail = $sourceEmail;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function format(array $record)
|
||||
{
|
||||
$tags = array(
|
||||
'#logs',
|
||||
'#' . strtolower($record['level_name']),
|
||||
'#' . $record['channel'],
|
||||
);
|
||||
|
||||
foreach ($record['extra'] as $value) {
|
||||
$tags[] = '#' . $value;
|
||||
}
|
||||
|
||||
$subject = sprintf(
|
||||
'in %s: %s - %s',
|
||||
$this->source,
|
||||
$record['level_name'],
|
||||
$this->getShortMessage($record['message'])
|
||||
);
|
||||
|
||||
$record['flowdock'] = array(
|
||||
'source' => $this->source,
|
||||
'from_address' => $this->sourceEmail,
|
||||
'subject' => $subject,
|
||||
'content' => $record['message'],
|
||||
'tags' => $tags,
|
||||
'project' => $this->source,
|
||||
);
|
||||
|
||||
return $record;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function formatBatch(array $records)
|
||||
{
|
||||
$formatted = array();
|
||||
|
||||
foreach ($records as $record) {
|
||||
$formatted[] = $this->format($record);
|
||||
}
|
||||
|
||||
return $formatted;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getShortMessage($message)
|
||||
{
|
||||
$maxLength = 45;
|
||||
|
||||
if (strlen($message) > $maxLength) {
|
||||
$message = substr($message, 0, $maxLength - 4) . ' ...';
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
}
|
||||
36
src/composer/vendor/monolog/monolog/src/Monolog/Formatter/FormatterInterface.php
vendored
Normal file
36
src/composer/vendor/monolog/monolog/src/Monolog/Formatter/FormatterInterface.php
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Monolog package.
|
||||
*
|
||||
* (c) 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 Monolog\Formatter;
|
||||
|
||||
/**
|
||||
* Interface for formatters
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*/
|
||||
interface FormatterInterface
|
||||
{
|
||||
/**
|
||||
* Formats a log record.
|
||||
*
|
||||
* @param array $record A record to format
|
||||
* @return mixed The formatted record
|
||||
*/
|
||||
public function format(array $record);
|
||||
|
||||
/**
|
||||
* Formats a set of log records.
|
||||
*
|
||||
* @param array $records A set of records to format
|
||||
* @return mixed The formatted set of records
|
||||
*/
|
||||
public function formatBatch(array $records);
|
||||
}
|
||||
111
src/composer/vendor/monolog/monolog/src/Monolog/Formatter/GelfMessageFormatter.php
vendored
Normal file
111
src/composer/vendor/monolog/monolog/src/Monolog/Formatter/GelfMessageFormatter.php
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Monolog package.
|
||||
*
|
||||
* (c) 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 Monolog\Formatter;
|
||||
|
||||
use Monolog\Logger;
|
||||
use Gelf\Message;
|
||||
|
||||
/**
|
||||
* Serializes a log message to GELF
|
||||
* @see http://www.graylog2.org/about/gelf
|
||||
*
|
||||
* @author Matt Lehner <mlehner@gmail.com>
|
||||
*/
|
||||
class GelfMessageFormatter extends NormalizerFormatter
|
||||
{
|
||||
/**
|
||||
* @var string the name of the system for the Gelf log message
|
||||
*/
|
||||
protected $systemName;
|
||||
|
||||
/**
|
||||
* @var string a prefix for 'extra' fields from the Monolog record (optional)
|
||||
*/
|
||||
protected $extraPrefix;
|
||||
|
||||
/**
|
||||
* @var string a prefix for 'context' fields from the Monolog record (optional)
|
||||
*/
|
||||
protected $contextPrefix;
|
||||
|
||||
/**
|
||||
* Translates Monolog log levels to Graylog2 log priorities.
|
||||
*/
|
||||
private $logLevels = array(
|
||||
Logger::DEBUG => 7,
|
||||
Logger::INFO => 6,
|
||||
Logger::NOTICE => 5,
|
||||
Logger::WARNING => 4,
|
||||
Logger::ERROR => 3,
|
||||
Logger::CRITICAL => 2,
|
||||
Logger::ALERT => 1,
|
||||
Logger::EMERGENCY => 0,
|
||||
);
|
||||
|
||||
public function __construct($systemName = null, $extraPrefix = null, $contextPrefix = 'ctxt_')
|
||||
{
|
||||
parent::__construct('U.u');
|
||||
|
||||
$this->systemName = $systemName ?: gethostname();
|
||||
|
||||
$this->extraPrefix = $extraPrefix;
|
||||
$this->contextPrefix = $contextPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function format(array $record)
|
||||
{
|
||||
$record = parent::format($record);
|
||||
|
||||
if (!isset($record['datetime'], $record['message'], $record['level'])) {
|
||||
throw new \InvalidArgumentException('The record should at least contain datetime, message and level keys, '.var_export($record, true).' given');
|
||||
}
|
||||
|
||||
$message = new Message();
|
||||
$message
|
||||
->setTimestamp($record['datetime'])
|
||||
->setShortMessage((string) $record['message'])
|
||||
->setHost($this->systemName)
|
||||
->setLevel($this->logLevels[$record['level']]);
|
||||
|
||||
if (isset($record['channel'])) {
|
||||
$message->setFacility($record['channel']);
|
||||
}
|
||||
if (isset($record['extra']['line'])) {
|
||||
$message->setLine($record['extra']['line']);
|
||||
unset($record['extra']['line']);
|
||||
}
|
||||
if (isset($record['extra']['file'])) {
|
||||
$message->setFile($record['extra']['file']);
|
||||
unset($record['extra']['file']);
|
||||
}
|
||||
|
||||
foreach ($record['extra'] as $key => $val) {
|
||||
$message->setAdditional($this->extraPrefix . $key, is_scalar($val) ? $val : $this->toJson($val));
|
||||
}
|
||||
|
||||
foreach ($record['context'] as $key => $val) {
|
||||
$message->setAdditional($this->contextPrefix . $key, is_scalar($val) ? $val : $this->toJson($val));
|
||||
}
|
||||
|
||||
if (null === $message->getFile() && isset($record['context']['exception']['file'])) {
|
||||
if (preg_match("/^(.+):([0-9]+)$/", $record['context']['exception']['file'], $matches)) {
|
||||
$message->setFile($matches[1]);
|
||||
$message->setLine($matches[2]);
|
||||
}
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
}
|
||||
140
src/composer/vendor/monolog/monolog/src/Monolog/Formatter/HtmlFormatter.php
vendored
Normal file
140
src/composer/vendor/monolog/monolog/src/Monolog/Formatter/HtmlFormatter.php
vendored
Normal file
@@ -0,0 +1,140 @@
|
||||
<?php
|
||||
/*
|
||||
* This file is part of the Monolog package.
|
||||
*
|
||||
* (c) 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 Monolog\Formatter;
|
||||
|
||||
use Monolog\Logger;
|
||||
|
||||
/**
|
||||
* Formats incoming records into an HTML table
|
||||
*
|
||||
* This is especially useful for html email logging
|
||||
*
|
||||
* @author Tiago Brito <tlfbrito@gmail.com>
|
||||
*/
|
||||
class HtmlFormatter extends NormalizerFormatter
|
||||
{
|
||||
/**
|
||||
* Translates Monolog log levels to html color priorities.
|
||||
*/
|
||||
private $logLevels = array(
|
||||
Logger::DEBUG => '#cccccc',
|
||||
Logger::INFO => '#468847',
|
||||
Logger::NOTICE => '#3a87ad',
|
||||
Logger::WARNING => '#c09853',
|
||||
Logger::ERROR => '#f0ad4e',
|
||||
Logger::CRITICAL => '#FF7708',
|
||||
Logger::ALERT => '#C12A19',
|
||||
Logger::EMERGENCY => '#000000',
|
||||
);
|
||||
|
||||
/**
|
||||
* @param string $dateFormat The format of the timestamp: one supported by DateTime::format
|
||||
*/
|
||||
public function __construct($dateFormat = null)
|
||||
{
|
||||
parent::__construct($dateFormat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an HTML table row
|
||||
*
|
||||
* @param string $th Row header content
|
||||
* @param string $td Row standard cell content
|
||||
* @param bool $escapeTd false if td content must not be html escaped
|
||||
* @return string
|
||||
*/
|
||||
private function addRow($th, $td = ' ', $escapeTd = true)
|
||||
{
|
||||
$th = htmlspecialchars($th, ENT_NOQUOTES, 'UTF-8');
|
||||
if ($escapeTd) {
|
||||
$td = '<pre>'.htmlspecialchars($td, ENT_NOQUOTES, 'UTF-8').'</pre>';
|
||||
}
|
||||
|
||||
return "<tr style=\"padding: 4px;spacing: 0;text-align: left;\">\n<th style=\"background: #cccccc\" width=\"100px\">$th:</th>\n<td style=\"padding: 4px;spacing: 0;text-align: left;background: #eeeeee\">".$td."</td>\n</tr>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a HTML h1 tag
|
||||
*
|
||||
* @param string $title Text to be in the h1
|
||||
* @param integer $level Error level
|
||||
* @return string
|
||||
*/
|
||||
private function addTitle($title, $level)
|
||||
{
|
||||
$title = htmlspecialchars($title, ENT_NOQUOTES, 'UTF-8');
|
||||
|
||||
return '<h1 style="background: '.$this->logLevels[$level].';color: #ffffff;padding: 5px;" class="monolog-output">'.$title.'</h1>';
|
||||
}
|
||||
/**
|
||||
* Formats a log record.
|
||||
*
|
||||
* @param array $record A record to format
|
||||
* @return mixed The formatted record
|
||||
*/
|
||||
public function format(array $record)
|
||||
{
|
||||
$output = $this->addTitle($record['level_name'], $record['level']);
|
||||
$output .= '<table cellspacing="1" width="100%" class="monolog-output">';
|
||||
|
||||
$output .= $this->addRow('Message', (string) $record['message']);
|
||||
$output .= $this->addRow('Time', $record['datetime']->format($this->dateFormat));
|
||||
$output .= $this->addRow('Channel', $record['channel']);
|
||||
if ($record['context']) {
|
||||
$embeddedTable = '<table cellspacing="1" width="100%">';
|
||||
foreach ($record['context'] as $key => $value) {
|
||||
$embeddedTable .= $this->addRow($key, $this->convertToString($value));
|
||||
}
|
||||
$embeddedTable .= '</table>';
|
||||
$output .= $this->addRow('Context', $embeddedTable, false);
|
||||
}
|
||||
if ($record['extra']) {
|
||||
$embeddedTable = '<table cellspacing="1" width="100%">';
|
||||
foreach ($record['extra'] as $key => $value) {
|
||||
$embeddedTable .= $this->addRow($key, $this->convertToString($value));
|
||||
}
|
||||
$embeddedTable .= '</table>';
|
||||
$output .= $this->addRow('Extra', $embeddedTable, false);
|
||||
}
|
||||
|
||||
return $output.'</table>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a set of log records.
|
||||
*
|
||||
* @param array $records A set of records to format
|
||||
* @return mixed The formatted set of records
|
||||
*/
|
||||
public function formatBatch(array $records)
|
||||
{
|
||||
$message = '';
|
||||
foreach ($records as $record) {
|
||||
$message .= $this->format($record);
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
protected function convertToString($data)
|
||||
{
|
||||
if (null === $data || is_scalar($data)) {
|
||||
return (string) $data;
|
||||
}
|
||||
|
||||
$data = $this->normalize($data);
|
||||
if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
|
||||
return json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
|
||||
return str_replace('\\/', '/', json_encode($data));
|
||||
}
|
||||
}
|
||||
116
src/composer/vendor/monolog/monolog/src/Monolog/Formatter/JsonFormatter.php
vendored
Normal file
116
src/composer/vendor/monolog/monolog/src/Monolog/Formatter/JsonFormatter.php
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Monolog package.
|
||||
*
|
||||
* (c) 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 Monolog\Formatter;
|
||||
|
||||
/**
|
||||
* Encodes whatever record data is passed to it as json
|
||||
*
|
||||
* This can be useful to log to databases or remote APIs
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*/
|
||||
class JsonFormatter implements FormatterInterface
|
||||
{
|
||||
const BATCH_MODE_JSON = 1;
|
||||
const BATCH_MODE_NEWLINES = 2;
|
||||
|
||||
protected $batchMode;
|
||||
protected $appendNewline;
|
||||
|
||||
/**
|
||||
* @param int $batchMode
|
||||
*/
|
||||
public function __construct($batchMode = self::BATCH_MODE_JSON, $appendNewline = true)
|
||||
{
|
||||
$this->batchMode = $batchMode;
|
||||
$this->appendNewline = $appendNewline;
|
||||
}
|
||||
|
||||
/**
|
||||
* The batch mode option configures the formatting style for
|
||||
* multiple records. By default, multiple records will be
|
||||
* formatted as a JSON-encoded array. However, for
|
||||
* compatibility with some API endpoints, alternative styles
|
||||
* are available.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getBatchMode()
|
||||
{
|
||||
return $this->batchMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if newlines are appended to every formatted record
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isAppendingNewlines()
|
||||
{
|
||||
return $this->appendNewline;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function format(array $record)
|
||||
{
|
||||
return json_encode($record) . ($this->appendNewline ? "\n" : '');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function formatBatch(array $records)
|
||||
{
|
||||
switch ($this->batchMode) {
|
||||
case static::BATCH_MODE_NEWLINES:
|
||||
return $this->formatBatchNewlines($records);
|
||||
|
||||
case static::BATCH_MODE_JSON:
|
||||
default:
|
||||
return $this->formatBatchJson($records);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a JSON-encoded array of records.
|
||||
*
|
||||
* @param array $records
|
||||
* @return string
|
||||
*/
|
||||
protected function formatBatchJson(array $records)
|
||||
{
|
||||
return json_encode($records);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use new lines to separate records instead of a
|
||||
* JSON-encoded array.
|
||||
*
|
||||
* @param array $records
|
||||
* @return string
|
||||
*/
|
||||
protected function formatBatchNewlines(array $records)
|
||||
{
|
||||
$instance = $this;
|
||||
|
||||
$oldNewline = $this->appendNewline;
|
||||
$this->appendNewline = false;
|
||||
array_walk($records, function (&$value, $key) use ($instance) {
|
||||
$value = $instance->format($value);
|
||||
});
|
||||
$this->appendNewline = $oldNewline;
|
||||
|
||||
return implode("\n", $records);
|
||||
}
|
||||
}
|
||||
159
src/composer/vendor/monolog/monolog/src/Monolog/Formatter/LineFormatter.php
vendored
Normal file
159
src/composer/vendor/monolog/monolog/src/Monolog/Formatter/LineFormatter.php
vendored
Normal file
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Monolog package.
|
||||
*
|
||||
* (c) 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 Monolog\Formatter;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Formats incoming records into a one-line string
|
||||
*
|
||||
* This is especially useful for logging to files
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
* @author Christophe Coevoet <stof@notk.org>
|
||||
*/
|
||||
class LineFormatter extends NormalizerFormatter
|
||||
{
|
||||
const SIMPLE_FORMAT = "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n";
|
||||
|
||||
protected $format;
|
||||
protected $allowInlineLineBreaks;
|
||||
protected $ignoreEmptyContextAndExtra;
|
||||
protected $includeStacktraces;
|
||||
|
||||
/**
|
||||
* @param string $format The format of the message
|
||||
* @param string $dateFormat The format of the timestamp: one supported by DateTime::format
|
||||
* @param bool $allowInlineLineBreaks Whether to allow inline line breaks in log entries
|
||||
* @param bool $ignoreEmptyContextAndExtra
|
||||
*/
|
||||
public function __construct($format = null, $dateFormat = null, $allowInlineLineBreaks = false, $ignoreEmptyContextAndExtra = false)
|
||||
{
|
||||
$this->format = $format ?: static::SIMPLE_FORMAT;
|
||||
$this->allowInlineLineBreaks = $allowInlineLineBreaks;
|
||||
$this->ignoreEmptyContextAndExtra = $ignoreEmptyContextAndExtra;
|
||||
parent::__construct($dateFormat);
|
||||
}
|
||||
|
||||
public function includeStacktraces($include = true)
|
||||
{
|
||||
$this->includeStacktraces = $include;
|
||||
if ($this->includeStacktraces) {
|
||||
$this->allowInlineLineBreaks = true;
|
||||
}
|
||||
}
|
||||
|
||||
public function allowInlineLineBreaks($allow = true)
|
||||
{
|
||||
$this->allowInlineLineBreaks = $allow;
|
||||
}
|
||||
|
||||
public function ignoreEmptyContextAndExtra($ignore = true)
|
||||
{
|
||||
$this->ignoreEmptyContextAndExtra = $ignore;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function format(array $record)
|
||||
{
|
||||
$vars = parent::format($record);
|
||||
|
||||
$output = $this->format;
|
||||
|
||||
foreach ($vars['extra'] as $var => $val) {
|
||||
if (false !== strpos($output, '%extra.'.$var.'%')) {
|
||||
$output = str_replace('%extra.'.$var.'%', $this->stringify($val), $output);
|
||||
unset($vars['extra'][$var]);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->ignoreEmptyContextAndExtra) {
|
||||
if (empty($vars['context'])) {
|
||||
unset($vars['context']);
|
||||
$output = str_replace('%context%', '', $output);
|
||||
}
|
||||
|
||||
if (empty($vars['extra'])) {
|
||||
unset($vars['extra']);
|
||||
$output = str_replace('%extra%', '', $output);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($vars as $var => $val) {
|
||||
if (false !== strpos($output, '%'.$var.'%')) {
|
||||
$output = str_replace('%'.$var.'%', $this->stringify($val), $output);
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function formatBatch(array $records)
|
||||
{
|
||||
$message = '';
|
||||
foreach ($records as $record) {
|
||||
$message .= $this->format($record);
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
public function stringify($value)
|
||||
{
|
||||
return $this->replaceNewlines($this->convertToString($value));
|
||||
}
|
||||
|
||||
protected function normalizeException(Exception $e)
|
||||
{
|
||||
$previousText = '';
|
||||
if ($previous = $e->getPrevious()) {
|
||||
do {
|
||||
$previousText .= ', '.get_class($previous).'(code: '.$previous->getCode().'): '.$previous->getMessage().' at '.$previous->getFile().':'.$previous->getLine();
|
||||
} while ($previous = $previous->getPrevious());
|
||||
}
|
||||
|
||||
$str = '[object] ('.get_class($e).'(code: '.$e->getCode().'): '.$e->getMessage().' at '.$e->getFile().':'.$e->getLine().$previousText.')';
|
||||
if ($this->includeStacktraces) {
|
||||
$str .= "\n[stacktrace]\n".$e->getTraceAsString();
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
protected function convertToString($data)
|
||||
{
|
||||
if (null === $data || is_bool($data)) {
|
||||
return var_export($data, true);
|
||||
}
|
||||
|
||||
if (is_scalar($data)) {
|
||||
return (string) $data;
|
||||
}
|
||||
|
||||
if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
|
||||
return $this->toJson($data, true);
|
||||
}
|
||||
|
||||
return str_replace('\\/', '/', @json_encode($data));
|
||||
}
|
||||
|
||||
protected function replaceNewlines($str)
|
||||
{
|
||||
if ($this->allowInlineLineBreaks) {
|
||||
return $str;
|
||||
}
|
||||
|
||||
return strtr($str, array("\r\n" => ' ', "\r" => ' ', "\n" => ' '));
|
||||
}
|
||||
}
|
||||
47
src/composer/vendor/monolog/monolog/src/Monolog/Formatter/LogglyFormatter.php
vendored
Normal file
47
src/composer/vendor/monolog/monolog/src/Monolog/Formatter/LogglyFormatter.php
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Monolog package.
|
||||
*
|
||||
* (c) 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 Monolog\Formatter;
|
||||
|
||||
/**
|
||||
* Encodes message information into JSON in a format compatible with Loggly.
|
||||
*
|
||||
* @author Adam Pancutt <adam@pancutt.com>
|
||||
*/
|
||||
class LogglyFormatter extends JsonFormatter
|
||||
{
|
||||
/**
|
||||
* Overrides the default batch mode to new lines for compatibility with the
|
||||
* Loggly bulk API.
|
||||
*
|
||||
* @param integer $batchMode
|
||||
*/
|
||||
public function __construct($batchMode = self::BATCH_MODE_NEWLINES, $appendNewline = false)
|
||||
{
|
||||
parent::__construct($batchMode, $appendNewline);
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the 'timestamp' parameter for indexing by Loggly.
|
||||
*
|
||||
* @see https://www.loggly.com/docs/automated-parsing/#json
|
||||
* @see \Monolog\Formatter\JsonFormatter::format()
|
||||
*/
|
||||
public function format(array $record)
|
||||
{
|
||||
if (isset($record["datetime"]) && ($record["datetime"] instanceof \DateTime)) {
|
||||
$record["timestamp"] = $record["datetime"]->format("Y-m-d\TH:i:s.uO");
|
||||
// TODO 2.0 unset the 'datetime' parameter, retained for BC
|
||||
}
|
||||
|
||||
return parent::format($record);
|
||||
}
|
||||
}
|
||||
165
src/composer/vendor/monolog/monolog/src/Monolog/Formatter/LogstashFormatter.php
vendored
Normal file
165
src/composer/vendor/monolog/monolog/src/Monolog/Formatter/LogstashFormatter.php
vendored
Normal file
@@ -0,0 +1,165 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Monolog package.
|
||||
*
|
||||
* (c) 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 Monolog\Formatter;
|
||||
|
||||
/**
|
||||
* Serializes a log message to Logstash Event Format
|
||||
*
|
||||
* @see http://logstash.net/
|
||||
* @see https://github.com/logstash/logstash/blob/master/lib/logstash/event.rb
|
||||
*
|
||||
* @author Tim Mower <timothy.mower@gmail.com>
|
||||
*/
|
||||
class LogstashFormatter extends NormalizerFormatter
|
||||
{
|
||||
const V0 = 0;
|
||||
const V1 = 1;
|
||||
|
||||
/**
|
||||
* @var string the name of the system for the Logstash log message, used to fill the @source field
|
||||
*/
|
||||
protected $systemName;
|
||||
|
||||
/**
|
||||
* @var string an application name for the Logstash log message, used to fill the @type field
|
||||
*/
|
||||
protected $applicationName;
|
||||
|
||||
/**
|
||||
* @var string a prefix for 'extra' fields from the Monolog record (optional)
|
||||
*/
|
||||
protected $extraPrefix;
|
||||
|
||||
/**
|
||||
* @var string a prefix for 'context' fields from the Monolog record (optional)
|
||||
*/
|
||||
protected $contextPrefix;
|
||||
|
||||
/**
|
||||
* @var integer logstash format version to use
|
||||
*/
|
||||
protected $version;
|
||||
|
||||
/**
|
||||
* @param string $applicationName the application that sends the data, used as the "type" field of logstash
|
||||
* @param string $systemName the system/machine name, used as the "source" field of logstash, defaults to the hostname of the machine
|
||||
* @param string $extraPrefix prefix for extra keys inside logstash "fields"
|
||||
* @param string $contextPrefix prefix for context keys inside logstash "fields", defaults to ctxt_
|
||||
*/
|
||||
public function __construct($applicationName, $systemName = null, $extraPrefix = null, $contextPrefix = 'ctxt_', $version = self::V0)
|
||||
{
|
||||
// logstash requires a ISO 8601 format date with optional millisecond precision.
|
||||
parent::__construct('Y-m-d\TH:i:s.uP');
|
||||
|
||||
$this->systemName = $systemName ?: gethostname();
|
||||
$this->applicationName = $applicationName;
|
||||
$this->extraPrefix = $extraPrefix;
|
||||
$this->contextPrefix = $contextPrefix;
|
||||
$this->version = $version;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function format(array $record)
|
||||
{
|
||||
$record = parent::format($record);
|
||||
|
||||
if ($this->version === self::V1) {
|
||||
$message = $this->formatV1($record);
|
||||
} else {
|
||||
$message = $this->formatV0($record);
|
||||
}
|
||||
|
||||
return $this->toJson($message) . "\n";
|
||||
}
|
||||
|
||||
protected function formatV0(array $record)
|
||||
{
|
||||
if (empty($record['datetime'])) {
|
||||
$record['datetime'] = gmdate('c');
|
||||
}
|
||||
$message = array(
|
||||
'@timestamp' => $record['datetime'],
|
||||
'@source' => $this->systemName,
|
||||
'@fields' => array()
|
||||
);
|
||||
if (isset($record['message'])) {
|
||||
$message['@message'] = $record['message'];
|
||||
}
|
||||
if (isset($record['channel'])) {
|
||||
$message['@tags'] = array($record['channel']);
|
||||
$message['@fields']['channel'] = $record['channel'];
|
||||
}
|
||||
if (isset($record['level'])) {
|
||||
$message['@fields']['level'] = $record['level'];
|
||||
}
|
||||
if ($this->applicationName) {
|
||||
$message['@type'] = $this->applicationName;
|
||||
}
|
||||
if (isset($record['extra']['server'])) {
|
||||
$message['@source_host'] = $record['extra']['server'];
|
||||
}
|
||||
if (isset($record['extra']['url'])) {
|
||||
$message['@source_path'] = $record['extra']['url'];
|
||||
}
|
||||
if (!empty($record['extra'])) {
|
||||
foreach ($record['extra'] as $key => $val) {
|
||||
$message['@fields'][$this->extraPrefix . $key] = $val;
|
||||
}
|
||||
}
|
||||
if (!empty($record['context'])) {
|
||||
foreach ($record['context'] as $key => $val) {
|
||||
$message['@fields'][$this->contextPrefix . $key] = $val;
|
||||
}
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
protected function formatV1(array $record)
|
||||
{
|
||||
if (empty($record['datetime'])) {
|
||||
$record['datetime'] = gmdate('c');
|
||||
}
|
||||
$message = array(
|
||||
'@timestamp' => $record['datetime'],
|
||||
'@version' => 1,
|
||||
'host' => $this->systemName,
|
||||
);
|
||||
if (isset($record['message'])) {
|
||||
$message['message'] = $record['message'];
|
||||
}
|
||||
if (isset($record['channel'])) {
|
||||
$message['type'] = $record['channel'];
|
||||
$message['channel'] = $record['channel'];
|
||||
}
|
||||
if (isset($record['level_name'])) {
|
||||
$message['level'] = $record['level_name'];
|
||||
}
|
||||
if ($this->applicationName) {
|
||||
$message['type'] = $this->applicationName;
|
||||
}
|
||||
if (!empty($record['extra'])) {
|
||||
foreach ($record['extra'] as $key => $val) {
|
||||
$message[$this->extraPrefix . $key] = $val;
|
||||
}
|
||||
}
|
||||
if (!empty($record['context'])) {
|
||||
foreach ($record['context'] as $key => $val) {
|
||||
$message[$this->contextPrefix . $key] = $val;
|
||||
}
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
}
|
||||
105
src/composer/vendor/monolog/monolog/src/Monolog/Formatter/MongoDBFormatter.php
vendored
Normal file
105
src/composer/vendor/monolog/monolog/src/Monolog/Formatter/MongoDBFormatter.php
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Monolog package.
|
||||
*
|
||||
* (c) 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 Monolog\Formatter;
|
||||
|
||||
/**
|
||||
* Formats a record for use with the MongoDBHandler.
|
||||
*
|
||||
* @author Florian Plattner <me@florianplattner.de>
|
||||
*/
|
||||
class MongoDBFormatter implements FormatterInterface
|
||||
{
|
||||
private $exceptionTraceAsString;
|
||||
private $maxNestingLevel;
|
||||
|
||||
/**
|
||||
* @param int $maxNestingLevel 0 means infinite nesting, the $record itself is level 1, $record['context'] is 2
|
||||
* @param bool $exceptionTraceAsString set to false to log exception traces as a sub documents instead of strings
|
||||
*/
|
||||
public function __construct($maxNestingLevel = 3, $exceptionTraceAsString = true)
|
||||
{
|
||||
$this->maxNestingLevel = max($maxNestingLevel, 0);
|
||||
$this->exceptionTraceAsString = (bool) $exceptionTraceAsString;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function format(array $record)
|
||||
{
|
||||
return $this->formatArray($record);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function formatBatch(array $records)
|
||||
{
|
||||
foreach ($records as $key => $record) {
|
||||
$records[$key] = $this->format($record);
|
||||
}
|
||||
|
||||
return $records;
|
||||
}
|
||||
|
||||
protected function formatArray(array $record, $nestingLevel = 0)
|
||||
{
|
||||
if ($this->maxNestingLevel == 0 || $nestingLevel <= $this->maxNestingLevel) {
|
||||
foreach ($record as $name => $value) {
|
||||
if ($value instanceof \DateTime) {
|
||||
$record[$name] = $this->formatDate($value, $nestingLevel + 1);
|
||||
} elseif ($value instanceof \Exception) {
|
||||
$record[$name] = $this->formatException($value, $nestingLevel + 1);
|
||||
} elseif (is_array($value)) {
|
||||
$record[$name] = $this->formatArray($value, $nestingLevel + 1);
|
||||
} elseif (is_object($value)) {
|
||||
$record[$name] = $this->formatObject($value, $nestingLevel + 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$record = '[...]';
|
||||
}
|
||||
|
||||
return $record;
|
||||
}
|
||||
|
||||
protected function formatObject($value, $nestingLevel)
|
||||
{
|
||||
$objectVars = get_object_vars($value);
|
||||
$objectVars['class'] = get_class($value);
|
||||
|
||||
return $this->formatArray($objectVars, $nestingLevel);
|
||||
}
|
||||
|
||||
protected function formatException(\Exception $exception, $nestingLevel)
|
||||
{
|
||||
$formattedException = array(
|
||||
'class' => get_class($exception),
|
||||
'message' => $exception->getMessage(),
|
||||
'code' => $exception->getCode(),
|
||||
'file' => $exception->getFile() . ':' . $exception->getLine(),
|
||||
);
|
||||
|
||||
if ($this->exceptionTraceAsString === true) {
|
||||
$formattedException['trace'] = $exception->getTraceAsString();
|
||||
} else {
|
||||
$formattedException['trace'] = $exception->getTrace();
|
||||
}
|
||||
|
||||
return $this->formatArray($formattedException, $nestingLevel);
|
||||
}
|
||||
|
||||
protected function formatDate(\DateTime $value, $nestingLevel)
|
||||
{
|
||||
return new \MongoDate($value->getTimestamp());
|
||||
}
|
||||
}
|
||||
150
src/composer/vendor/monolog/monolog/src/Monolog/Formatter/NormalizerFormatter.php
vendored
Normal file
150
src/composer/vendor/monolog/monolog/src/Monolog/Formatter/NormalizerFormatter.php
vendored
Normal file
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Monolog package.
|
||||
*
|
||||
* (c) 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 Monolog\Formatter;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Normalizes incoming records to remove objects/resources so it's easier to dump to various targets
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*/
|
||||
class NormalizerFormatter implements FormatterInterface
|
||||
{
|
||||
const SIMPLE_DATE = "Y-m-d H:i:s";
|
||||
|
||||
protected $dateFormat;
|
||||
|
||||
/**
|
||||
* @param string $dateFormat The format of the timestamp: one supported by DateTime::format
|
||||
*/
|
||||
public function __construct($dateFormat = null)
|
||||
{
|
||||
$this->dateFormat = $dateFormat ?: static::SIMPLE_DATE;
|
||||
if (!function_exists('json_encode')) {
|
||||
throw new \RuntimeException('PHP\'s json extension is required to use Monolog\'s NormalizerFormatter');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function format(array $record)
|
||||
{
|
||||
return $this->normalize($record);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function formatBatch(array $records)
|
||||
{
|
||||
foreach ($records as $key => $record) {
|
||||
$records[$key] = $this->format($record);
|
||||
}
|
||||
|
||||
return $records;
|
||||
}
|
||||
|
||||
protected function normalize($data)
|
||||
{
|
||||
if (null === $data || is_scalar($data)) {
|
||||
if (is_float($data)) {
|
||||
if (is_infinite($data)) {
|
||||
return ($data > 0 ? '' : '-') . 'INF';
|
||||
}
|
||||
if (is_nan($data)) {
|
||||
return 'NaN';
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
if (is_array($data) || $data instanceof \Traversable) {
|
||||
$normalized = array();
|
||||
|
||||
$count = 1;
|
||||
foreach ($data as $key => $value) {
|
||||
if ($count++ >= 1000) {
|
||||
$normalized['...'] = 'Over 1000 items, aborting normalization';
|
||||
break;
|
||||
}
|
||||
$normalized[$key] = $this->normalize($value);
|
||||
}
|
||||
|
||||
return $normalized;
|
||||
}
|
||||
|
||||
if ($data instanceof \DateTime) {
|
||||
return $data->format($this->dateFormat);
|
||||
}
|
||||
|
||||
if (is_object($data)) {
|
||||
if ($data instanceof Exception) {
|
||||
return $this->normalizeException($data);
|
||||
}
|
||||
|
||||
return sprintf("[object] (%s: %s)", get_class($data), $this->toJson($data, true));
|
||||
}
|
||||
|
||||
if (is_resource($data)) {
|
||||
return '[resource]';
|
||||
}
|
||||
|
||||
return '[unknown('.gettype($data).')]';
|
||||
}
|
||||
|
||||
protected function normalizeException(Exception $e)
|
||||
{
|
||||
$data = array(
|
||||
'class' => get_class($e),
|
||||
'message' => $e->getMessage(),
|
||||
'code' => $e->getCode(),
|
||||
'file' => $e->getFile().':'.$e->getLine(),
|
||||
);
|
||||
|
||||
$trace = $e->getTrace();
|
||||
foreach ($trace as $frame) {
|
||||
if (isset($frame['file'])) {
|
||||
$data['trace'][] = $frame['file'].':'.$frame['line'];
|
||||
} else {
|
||||
// We should again normalize the frames, because it might contain invalid items
|
||||
$data['trace'][] = $this->toJson($this->normalize($frame), true);
|
||||
}
|
||||
}
|
||||
|
||||
if ($previous = $e->getPrevious()) {
|
||||
$data['previous'] = $this->normalizeException($previous);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
protected function toJson($data, $ignoreErrors = false)
|
||||
{
|
||||
// suppress json_encode errors since it's twitchy with some inputs
|
||||
if ($ignoreErrors) {
|
||||
if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
|
||||
return @json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
|
||||
return @json_encode($data);
|
||||
}
|
||||
|
||||
if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
|
||||
return json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
|
||||
return json_encode($data);
|
||||
}
|
||||
}
|
||||
48
src/composer/vendor/monolog/monolog/src/Monolog/Formatter/ScalarFormatter.php
vendored
Normal file
48
src/composer/vendor/monolog/monolog/src/Monolog/Formatter/ScalarFormatter.php
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Monolog package.
|
||||
*
|
||||
* (c) 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 Monolog\Formatter;
|
||||
|
||||
/**
|
||||
* Formats data into an associative array of scalar values.
|
||||
* Objects and arrays will be JSON encoded.
|
||||
*
|
||||
* @author Andrew Lawson <adlawson@gmail.com>
|
||||
*/
|
||||
class ScalarFormatter extends NormalizerFormatter
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function format(array $record)
|
||||
{
|
||||
foreach ($record as $key => $value) {
|
||||
$record[$key] = $this->normalizeValue($value);
|
||||
}
|
||||
|
||||
return $record;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
* @return mixed
|
||||
*/
|
||||
protected function normalizeValue($value)
|
||||
{
|
||||
$normalized = $this->normalize($value);
|
||||
|
||||
if (is_array($normalized) || is_object($normalized)) {
|
||||
return $this->toJson($normalized, true);
|
||||
}
|
||||
|
||||
return $normalized;
|
||||
}
|
||||
}
|
||||
113
src/composer/vendor/monolog/monolog/src/Monolog/Formatter/WildfireFormatter.php
vendored
Normal file
113
src/composer/vendor/monolog/monolog/src/Monolog/Formatter/WildfireFormatter.php
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Monolog package.
|
||||
*
|
||||
* (c) 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 Monolog\Formatter;
|
||||
|
||||
use Monolog\Logger;
|
||||
|
||||
/**
|
||||
* Serializes a log message according to Wildfire's header requirements
|
||||
*
|
||||
* @author Eric Clemmons (@ericclemmons) <eric@uxdriven.com>
|
||||
* @author Christophe Coevoet <stof@notk.org>
|
||||
* @author Kirill chEbba Chebunin <iam@chebba.org>
|
||||
*/
|
||||
class WildfireFormatter extends NormalizerFormatter
|
||||
{
|
||||
const TABLE = 'table';
|
||||
|
||||
/**
|
||||
* Translates Monolog log levels to Wildfire levels.
|
||||
*/
|
||||
private $logLevels = array(
|
||||
Logger::DEBUG => 'LOG',
|
||||
Logger::INFO => 'INFO',
|
||||
Logger::NOTICE => 'INFO',
|
||||
Logger::WARNING => 'WARN',
|
||||
Logger::ERROR => 'ERROR',
|
||||
Logger::CRITICAL => 'ERROR',
|
||||
Logger::ALERT => 'ERROR',
|
||||
Logger::EMERGENCY => 'ERROR',
|
||||
);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function format(array $record)
|
||||
{
|
||||
// Retrieve the line and file if set and remove them from the formatted extra
|
||||
$file = $line = '';
|
||||
if (isset($record['extra']['file'])) {
|
||||
$file = $record['extra']['file'];
|
||||
unset($record['extra']['file']);
|
||||
}
|
||||
if (isset($record['extra']['line'])) {
|
||||
$line = $record['extra']['line'];
|
||||
unset($record['extra']['line']);
|
||||
}
|
||||
|
||||
$record = $this->normalize($record);
|
||||
$message = array('message' => $record['message']);
|
||||
$handleError = false;
|
||||
if ($record['context']) {
|
||||
$message['context'] = $record['context'];
|
||||
$handleError = true;
|
||||
}
|
||||
if ($record['extra']) {
|
||||
$message['extra'] = $record['extra'];
|
||||
$handleError = true;
|
||||
}
|
||||
if (count($message) === 1) {
|
||||
$message = reset($message);
|
||||
}
|
||||
|
||||
if (isset($record['context'][self::TABLE])) {
|
||||
$type = 'TABLE';
|
||||
$label = $record['channel'] .': '. $record['message'];
|
||||
$message = $record['context'][self::TABLE];
|
||||
} else {
|
||||
$type = $this->logLevels[$record['level']];
|
||||
$label = $record['channel'];
|
||||
}
|
||||
|
||||
// Create JSON object describing the appearance of the message in the console
|
||||
$json = $this->toJson(array(
|
||||
array(
|
||||
'Type' => $type,
|
||||
'File' => $file,
|
||||
'Line' => $line,
|
||||
'Label' => $label,
|
||||
),
|
||||
$message,
|
||||
), $handleError);
|
||||
|
||||
// The message itself is a serialization of the above JSON object + it's length
|
||||
return sprintf(
|
||||
'%s|%s|',
|
||||
strlen($json),
|
||||
$json
|
||||
);
|
||||
}
|
||||
|
||||
public function formatBatch(array $records)
|
||||
{
|
||||
throw new \BadMethodCallException('Batch formatting does not make sense for the WildfireFormatter');
|
||||
}
|
||||
|
||||
protected function normalize($data)
|
||||
{
|
||||
if (is_object($data) && !$data instanceof \DateTime) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
return parent::normalize($data);
|
||||
}
|
||||
}
|
||||
184
src/composer/vendor/monolog/monolog/src/Monolog/Handler/AbstractHandler.php
vendored
Normal file
184
src/composer/vendor/monolog/monolog/src/Monolog/Handler/AbstractHandler.php
vendored
Normal file
@@ -0,0 +1,184 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Monolog package.
|
||||
*
|
||||
* (c) 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 Monolog\Handler;
|
||||
|
||||
use Monolog\Logger;
|
||||
use Monolog\Formatter\FormatterInterface;
|
||||
use Monolog\Formatter\LineFormatter;
|
||||
|
||||
/**
|
||||
* Base Handler class providing the Handler structure
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*/
|
||||
abstract class AbstractHandler implements HandlerInterface
|
||||
{
|
||||
protected $level = Logger::DEBUG;
|
||||
protected $bubble = true;
|
||||
|
||||
/**
|
||||
* @var FormatterInterface
|
||||
*/
|
||||
protected $formatter;
|
||||
protected $processors = array();
|
||||
|
||||
/**
|
||||
* @param integer $level The minimum logging level at which this handler will be triggered
|
||||
* @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
|
||||
*/
|
||||
public function __construct($level = Logger::DEBUG, $bubble = true)
|
||||
{
|
||||
$this->setLevel($level);
|
||||
$this->bubble = $bubble;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isHandling(array $record)
|
||||
{
|
||||
return $record['level'] >= $this->level;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function handleBatch(array $records)
|
||||
{
|
||||
foreach ($records as $record) {
|
||||
$this->handle($record);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the handler.
|
||||
*
|
||||
* This will be called automatically when the object is destroyed
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function pushProcessor($callback)
|
||||
{
|
||||
if (!is_callable($callback)) {
|
||||
throw new \InvalidArgumentException('Processors must be valid callables (callback or object with an __invoke method), '.var_export($callback, true).' given');
|
||||
}
|
||||
array_unshift($this->processors, $callback);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function popProcessor()
|
||||
{
|
||||
if (!$this->processors) {
|
||||
throw new \LogicException('You tried to pop from an empty processor stack.');
|
||||
}
|
||||
|
||||
return array_shift($this->processors);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setFormatter(FormatterInterface $formatter)
|
||||
{
|
||||
$this->formatter = $formatter;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormatter()
|
||||
{
|
||||
if (!$this->formatter) {
|
||||
$this->formatter = $this->getDefaultFormatter();
|
||||
}
|
||||
|
||||
return $this->formatter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets minimum logging level at which this handler will be triggered.
|
||||
*
|
||||
* @param integer $level
|
||||
* @return self
|
||||
*/
|
||||
public function setLevel($level)
|
||||
{
|
||||
$this->level = Logger::toMonologLevel($level);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets minimum logging level at which this handler will be triggered.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getLevel()
|
||||
{
|
||||
return $this->level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the bubbling behavior.
|
||||
*
|
||||
* @param Boolean $bubble true means that this handler allows bubbling.
|
||||
* false means that bubbling is not permitted.
|
||||
* @return self
|
||||
*/
|
||||
public function setBubble($bubble)
|
||||
{
|
||||
$this->bubble = $bubble;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bubbling behavior.
|
||||
*
|
||||
* @return Boolean true means that this handler allows bubbling.
|
||||
* false means that bubbling is not permitted.
|
||||
*/
|
||||
public function getBubble()
|
||||
{
|
||||
return $this->bubble;
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
try {
|
||||
$this->close();
|
||||
} catch (\Exception $e) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default formatter.
|
||||
*
|
||||
* @return FormatterInterface
|
||||
*/
|
||||
protected function getDefaultFormatter()
|
||||
{
|
||||
return new LineFormatter();
|
||||
}
|
||||
}
|
||||
66
src/composer/vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php
vendored
Normal file
66
src/composer/vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Monolog package.
|
||||
*
|
||||
* (c) 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 Monolog\Handler;
|
||||
|
||||
/**
|
||||
* Base Handler class providing the Handler structure
|
||||
*
|
||||
* Classes extending it should (in most cases) only implement write($record)
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
* @author Christophe Coevoet <stof@notk.org>
|
||||
*/
|
||||
abstract class AbstractProcessingHandler extends AbstractHandler
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function handle(array $record)
|
||||
{
|
||||
if (!$this->isHandling($record)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$record = $this->processRecord($record);
|
||||
|
||||
$record['formatted'] = $this->getFormatter()->format($record);
|
||||
|
||||
$this->write($record);
|
||||
|
||||
return false === $this->bubble;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the record down to the log of the implementing handler
|
||||
*
|
||||
* @param array $record
|
||||
* @return void
|
||||
*/
|
||||
abstract protected function write(array $record);
|
||||
|
||||
/**
|
||||
* Processes a record.
|
||||
*
|
||||
* @param array $record
|
||||
* @return array
|
||||
*/
|
||||
protected function processRecord(array $record)
|
||||
{
|
||||
if ($this->processors) {
|
||||
foreach ($this->processors as $processor) {
|
||||
$record = call_user_func($processor, $record);
|
||||
}
|
||||
}
|
||||
|
||||
return $record;
|
||||
}
|
||||
}
|
||||
92
src/composer/vendor/monolog/monolog/src/Monolog/Handler/AbstractSyslogHandler.php
vendored
Normal file
92
src/composer/vendor/monolog/monolog/src/Monolog/Handler/AbstractSyslogHandler.php
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Monolog package.
|
||||
*
|
||||
* (c) 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 Monolog\Handler;
|
||||
|
||||
use Monolog\Logger;
|
||||
use Monolog\Formatter\LineFormatter;
|
||||
|
||||
/**
|
||||
* Common syslog functionality
|
||||
*/
|
||||
abstract class AbstractSyslogHandler extends AbstractProcessingHandler
|
||||
{
|
||||
protected $facility;
|
||||
|
||||
/**
|
||||
* Translates Monolog log levels to syslog log priorities.
|
||||
*/
|
||||
protected $logLevels = array(
|
||||
Logger::DEBUG => LOG_DEBUG,
|
||||
Logger::INFO => LOG_INFO,
|
||||
Logger::NOTICE => LOG_NOTICE,
|
||||
Logger::WARNING => LOG_WARNING,
|
||||
Logger::ERROR => LOG_ERR,
|
||||
Logger::CRITICAL => LOG_CRIT,
|
||||
Logger::ALERT => LOG_ALERT,
|
||||
Logger::EMERGENCY => LOG_EMERG,
|
||||
);
|
||||
|
||||
/**
|
||||
* List of valid log facility names.
|
||||
*/
|
||||
protected $facilities = array(
|
||||
'auth' => LOG_AUTH,
|
||||
'authpriv' => LOG_AUTHPRIV,
|
||||
'cron' => LOG_CRON,
|
||||
'daemon' => LOG_DAEMON,
|
||||
'kern' => LOG_KERN,
|
||||
'lpr' => LOG_LPR,
|
||||
'mail' => LOG_MAIL,
|
||||
'news' => LOG_NEWS,
|
||||
'syslog' => LOG_SYSLOG,
|
||||
'user' => LOG_USER,
|
||||
'uucp' => LOG_UUCP,
|
||||
);
|
||||
|
||||
/**
|
||||
* @param mixed $facility
|
||||
* @param integer $level The minimum logging level at which this handler will be triggered
|
||||
* @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
|
||||
*/
|
||||
public function __construct($facility = LOG_USER, $level = Logger::DEBUG, $bubble = true)
|
||||
{
|
||||
parent::__construct($level, $bubble);
|
||||
|
||||
if (!defined('PHP_WINDOWS_VERSION_BUILD')) {
|
||||
$this->facilities['local0'] = LOG_LOCAL0;
|
||||
$this->facilities['local1'] = LOG_LOCAL1;
|
||||
$this->facilities['local2'] = LOG_LOCAL2;
|
||||
$this->facilities['local3'] = LOG_LOCAL3;
|
||||
$this->facilities['local4'] = LOG_LOCAL4;
|
||||
$this->facilities['local5'] = LOG_LOCAL5;
|
||||
$this->facilities['local6'] = LOG_LOCAL6;
|
||||
$this->facilities['local7'] = LOG_LOCAL7;
|
||||
}
|
||||
|
||||
// convert textual description of facility to syslog constant
|
||||
if (array_key_exists(strtolower($facility), $this->facilities)) {
|
||||
$facility = $this->facilities[strtolower($facility)];
|
||||
} elseif (!in_array($facility, array_values($this->facilities), true)) {
|
||||
throw new \UnexpectedValueException('Unknown facility value "'.$facility.'" given');
|
||||
}
|
||||
|
||||
$this->facility = $facility;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getDefaultFormatter()
|
||||
{
|
||||
return new LineFormatter('%channel%.%level_name%: %message% %context% %extra%');
|
||||
}
|
||||
}
|
||||
98
src/composer/vendor/monolog/monolog/src/Monolog/Handler/AmqpHandler.php
vendored
Normal file
98
src/composer/vendor/monolog/monolog/src/Monolog/Handler/AmqpHandler.php
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Monolog package.
|
||||
*
|
||||
* (c) 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 Monolog\Handler;
|
||||
|
||||
use Monolog\Logger;
|
||||
use Monolog\Formatter\JsonFormatter;
|
||||
use PhpAmqpLib\Message\AMQPMessage;
|
||||
use PhpAmqpLib\Channel\AMQPChannel;
|
||||
use AMQPExchange;
|
||||
|
||||
class AmqpHandler extends AbstractProcessingHandler
|
||||
{
|
||||
/**
|
||||
* @var AMQPExchange|AMQPChannel $exchange
|
||||
*/
|
||||
protected $exchange;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $exchangeName;
|
||||
|
||||
/**
|
||||
* @param AMQPExchange|AMQPChannel $exchange AMQPExchange (php AMQP ext) or PHP AMQP lib channel, ready for use
|
||||
* @param string $exchangeName
|
||||
* @param int $level
|
||||
* @param bool $bubble Whether the messages that are handled can bubble up the stack or not
|
||||
*/
|
||||
public function __construct($exchange, $exchangeName = 'log', $level = Logger::DEBUG, $bubble = true)
|
||||
{
|
||||
if ($exchange instanceof AMQPExchange) {
|
||||
$exchange->setName($exchangeName);
|
||||
} elseif ($exchange instanceof AMQPChannel) {
|
||||
$this->exchangeName = $exchangeName;
|
||||
} else {
|
||||
throw new \InvalidArgumentException('PhpAmqpLib\Channel\AMQPChannel or AMQPExchange instance required');
|
||||
}
|
||||
$this->exchange = $exchange;
|
||||
|
||||
parent::__construct($level, $bubble);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function write(array $record)
|
||||
{
|
||||
$data = $record["formatted"];
|
||||
|
||||
$routingKey = sprintf(
|
||||
'%s.%s',
|
||||
// TODO 2.0 remove substr call
|
||||
substr($record['level_name'], 0, 4),
|
||||
$record['channel']
|
||||
);
|
||||
|
||||
if ($this->exchange instanceof AMQPExchange) {
|
||||
$this->exchange->publish(
|
||||
$data,
|
||||
strtolower($routingKey),
|
||||
0,
|
||||
array(
|
||||
'delivery_mode' => 2,
|
||||
'Content-type' => 'application/json'
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$this->exchange->basic_publish(
|
||||
new AMQPMessage(
|
||||
(string) $data,
|
||||
array(
|
||||
'delivery_mode' => 2,
|
||||
'content_type' => 'application/json'
|
||||
)
|
||||
),
|
||||
$this->exchangeName,
|
||||
strtolower($routingKey)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function getDefaultFormatter()
|
||||
{
|
||||
return new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, false);
|
||||
}
|
||||
}
|
||||
184
src/composer/vendor/monolog/monolog/src/Monolog/Handler/BrowserConsoleHandler.php
vendored
Normal file
184
src/composer/vendor/monolog/monolog/src/Monolog/Handler/BrowserConsoleHandler.php
vendored
Normal file
@@ -0,0 +1,184 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Monolog package.
|
||||
*
|
||||
* (c) 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 Monolog\Handler;
|
||||
|
||||
use Monolog\Formatter\LineFormatter;
|
||||
|
||||
/**
|
||||
* Handler sending logs to browser's javascript console with no browser extension required
|
||||
*
|
||||
* @author Olivier Poitrey <rs@dailymotion.com>
|
||||
*/
|
||||
class BrowserConsoleHandler extends AbstractProcessingHandler
|
||||
{
|
||||
protected static $initialized = false;
|
||||
protected static $records = array();
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* Formatted output may contain some formatting markers to be transferred to `console.log` using the %c format.
|
||||
*
|
||||
* Example of formatted string:
|
||||
*
|
||||
* You can do [[blue text]]{color: blue} or [[green background]]{background-color: green; color: white}
|
||||
*
|
||||
*/
|
||||
protected function getDefaultFormatter()
|
||||
{
|
||||
return new LineFormatter('[[%channel%]]{macro: autolabel} [[%level_name%]]{font-weight: bold} %message%');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function write(array $record)
|
||||
{
|
||||
// Accumulate records
|
||||
self::$records[] = $record;
|
||||
|
||||
// Register shutdown handler if not already done
|
||||
if (PHP_SAPI !== 'cli' && !self::$initialized) {
|
||||
self::$initialized = true;
|
||||
register_shutdown_function(array('Monolog\Handler\BrowserConsoleHandler', 'send'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert records to javascript console commands and send it to the browser.
|
||||
* This method is automatically called on PHP shutdown if output is HTML.
|
||||
*/
|
||||
public static function send()
|
||||
{
|
||||
// Check content type
|
||||
foreach (headers_list() as $header) {
|
||||
if (stripos($header, 'content-type:') === 0) {
|
||||
if (stripos($header, 'text/html') === false) {
|
||||
// This handler only works with HTML outputs
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (count(self::$records)) {
|
||||
echo '<script>' . self::generateScript() . '</script>';
|
||||
self::reset();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Forget all logged records
|
||||
*/
|
||||
public static function reset()
|
||||
{
|
||||
self::$records = array();
|
||||
}
|
||||
|
||||
private static function generateScript()
|
||||
{
|
||||
$script = array();
|
||||
foreach (self::$records as $record) {
|
||||
$context = self::dump('Context', $record['context']);
|
||||
$extra = self::dump('Extra', $record['extra']);
|
||||
|
||||
if (empty($context) && empty($extra)) {
|
||||
$script[] = self::call_array('log', self::handleStyles($record['formatted']));
|
||||
} else {
|
||||
$script = array_merge($script,
|
||||
array(self::call_array('groupCollapsed', self::handleStyles($record['formatted']))),
|
||||
$context,
|
||||
$extra,
|
||||
array(self::call('groupEnd'))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return "(function (c) {if (c && c.groupCollapsed) {\n" . implode("\n", $script) . "\n}})(console);";
|
||||
}
|
||||
|
||||
private static function handleStyles($formatted)
|
||||
{
|
||||
$args = array(self::quote('font-weight: normal'));
|
||||
$format = '%c' . $formatted;
|
||||
preg_match_all('/\[\[(.*?)\]\]\{([^}]*)\}/s', $format, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER);
|
||||
|
||||
foreach (array_reverse($matches) as $match) {
|
||||
$args[] = self::quote(self::handleCustomStyles($match[2][0], $match[1][0]));
|
||||
$args[] = '"font-weight: normal"';
|
||||
|
||||
$pos = $match[0][1];
|
||||
$format = substr($format, 0, $pos) . '%c' . $match[1][0] . '%c' . substr($format, $pos + strlen($match[0][0]));
|
||||
}
|
||||
|
||||
array_unshift($args, self::quote($format));
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
private static function handleCustomStyles($style, $string)
|
||||
{
|
||||
static $colors = array('blue', 'green', 'red', 'magenta', 'orange', 'black', 'grey');
|
||||
static $labels = array();
|
||||
|
||||
return preg_replace_callback('/macro\s*:(.*?)(?:;|$)/', function ($m) use ($string, &$colors, &$labels) {
|
||||
if (trim($m[1]) === 'autolabel') {
|
||||
// Format the string as a label with consistent auto assigned background color
|
||||
if (!isset($labels[$string])) {
|
||||
$labels[$string] = $colors[count($labels) % count($colors)];
|
||||
}
|
||||
$color = $labels[$string];
|
||||
|
||||
return "background-color: $color; color: white; border-radius: 3px; padding: 0 2px 0 2px";
|
||||
}
|
||||
|
||||
return $m[1];
|
||||
}, $style);
|
||||
}
|
||||
|
||||
private static function dump($title, array $dict)
|
||||
{
|
||||
$script = array();
|
||||
$dict = array_filter($dict);
|
||||
if (empty($dict)) {
|
||||
return $script;
|
||||
}
|
||||
$script[] = self::call('log', self::quote('%c%s'), self::quote('font-weight: bold'), self::quote($title));
|
||||
foreach ($dict as $key => $value) {
|
||||
$value = json_encode($value);
|
||||
if (empty($value)) {
|
||||
$value = self::quote('');
|
||||
}
|
||||
$script[] = self::call('log', self::quote('%s: %o'), self::quote($key), $value);
|
||||
}
|
||||
|
||||
return $script;
|
||||
}
|
||||
|
||||
private static function quote($arg)
|
||||
{
|
||||
return '"' . addcslashes($arg, "\"\n") . '"';
|
||||
}
|
||||
|
||||
private static function call()
|
||||
{
|
||||
$args = func_get_args();
|
||||
$method = array_shift($args);
|
||||
|
||||
return self::call_array($method, $args);
|
||||
}
|
||||
|
||||
private static function call_array($method, array $args)
|
||||
{
|
||||
return 'c.' . $method . '(' . implode(', ', $args) . ');';
|
||||
}
|
||||
}
|
||||
117
src/composer/vendor/monolog/monolog/src/Monolog/Handler/BufferHandler.php
vendored
Normal file
117
src/composer/vendor/monolog/monolog/src/Monolog/Handler/BufferHandler.php
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Monolog package.
|
||||
*
|
||||
* (c) 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 Monolog\Handler;
|
||||
|
||||
use Monolog\Logger;
|
||||
|
||||
/**
|
||||
* Buffers all records until closing the handler and then pass them as batch.
|
||||
*
|
||||
* This is useful for a MailHandler to send only one mail per request instead of
|
||||
* sending one per log message.
|
||||
*
|
||||
* @author Christophe Coevoet <stof@notk.org>
|
||||
*/
|
||||
class BufferHandler extends AbstractHandler
|
||||
{
|
||||
protected $handler;
|
||||
protected $bufferSize = 0;
|
||||
protected $bufferLimit;
|
||||
protected $flushOnOverflow;
|
||||
protected $buffer = array();
|
||||
protected $initialized = false;
|
||||
|
||||
/**
|
||||
* @param HandlerInterface $handler Handler.
|
||||
* @param integer $bufferLimit How many entries should be buffered at most, beyond that the oldest items are removed from the buffer.
|
||||
* @param integer $level The minimum logging level at which this handler will be triggered
|
||||
* @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
|
||||
* @param Boolean $flushOnOverflow If true, the buffer is flushed when the max size has been reached, by default oldest entries are discarded
|
||||
*/
|
||||
public function __construct(HandlerInterface $handler, $bufferLimit = 0, $level = Logger::DEBUG, $bubble = true, $flushOnOverflow = false)
|
||||
{
|
||||
parent::__construct($level, $bubble);
|
||||
$this->handler = $handler;
|
||||
$this->bufferLimit = (int) $bufferLimit;
|
||||
$this->flushOnOverflow = $flushOnOverflow;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function handle(array $record)
|
||||
{
|
||||
if ($record['level'] < $this->level) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->initialized) {
|
||||
// __destructor() doesn't get called on Fatal errors
|
||||
register_shutdown_function(array($this, 'close'));
|
||||
$this->initialized = true;
|
||||
}
|
||||
|
||||
if ($this->bufferLimit > 0 && $this->bufferSize === $this->bufferLimit) {
|
||||
if ($this->flushOnOverflow) {
|
||||
$this->flush();
|
||||
} else {
|
||||
array_shift($this->buffer);
|
||||
$this->bufferSize--;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->processors) {
|
||||
foreach ($this->processors as $processor) {
|
||||
$record = call_user_func($processor, $record);
|
||||
}
|
||||
}
|
||||
|
||||
$this->buffer[] = $record;
|
||||
$this->bufferSize++;
|
||||
|
||||
return false === $this->bubble;
|
||||
}
|
||||
|
||||
public function flush()
|
||||
{
|
||||
if ($this->bufferSize === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->handler->handleBatch($this->buffer);
|
||||
$this->clear();
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
// suppress the parent behavior since we already have register_shutdown_function()
|
||||
// to call close(), and the reference contained there will prevent this from being
|
||||
// GC'd until the end of the request
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
$this->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the buffer without flushing any messages down to the wrapped handler.
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
$this->bufferSize = 0;
|
||||
$this->buffer = array();
|
||||
}
|
||||
}
|
||||
204
src/composer/vendor/monolog/monolog/src/Monolog/Handler/ChromePHPHandler.php
vendored
Normal file
204
src/composer/vendor/monolog/monolog/src/Monolog/Handler/ChromePHPHandler.php
vendored
Normal file
@@ -0,0 +1,204 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Monolog package.
|
||||
*
|
||||
* (c) 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 Monolog\Handler;
|
||||
|
||||
use Monolog\Formatter\ChromePHPFormatter;
|
||||
use Monolog\Logger;
|
||||
|
||||
/**
|
||||
* Handler sending logs to the ChromePHP extension (http://www.chromephp.com/)
|
||||
*
|
||||
* @author Christophe Coevoet <stof@notk.org>
|
||||
*/
|
||||
class ChromePHPHandler extends AbstractProcessingHandler
|
||||
{
|
||||
/**
|
||||
* Version of the extension
|
||||
*/
|
||||
const VERSION = '4.0';
|
||||
|
||||
/**
|
||||
* Header name
|
||||
*/
|
||||
const HEADER_NAME = 'X-ChromeLogger-Data';
|
||||
|
||||
protected static $initialized = false;
|
||||
|
||||
/**
|
||||
* Tracks whether we sent too much data
|
||||
*
|
||||
* Chrome limits the headers to 256KB, so when we sent 240KB we stop sending
|
||||
*
|
||||
* @var Boolean
|
||||
*/
|
||||
protected static $overflowed = false;
|
||||
|
||||
protected static $json = array(
|
||||
'version' => self::VERSION,
|
||||
'columns' => array('label', 'log', 'backtrace', 'type'),
|
||||
'rows' => array(),
|
||||
);
|
||||
|
||||
protected static $sendHeaders = true;
|
||||
|
||||
/**
|
||||
* @param integer $level The minimum logging level at which this handler will be triggered
|
||||
* @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
|
||||
*/
|
||||
public function __construct($level = Logger::DEBUG, $bubble = true)
|
||||
{
|
||||
parent::__construct($level, $bubble);
|
||||
if (!function_exists('json_encode')) {
|
||||
throw new \RuntimeException('PHP\'s json extension is required to use Monolog\'s ChromePHPHandler');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function handleBatch(array $records)
|
||||
{
|
||||
$messages = array();
|
||||
|
||||
foreach ($records as $record) {
|
||||
if ($record['level'] < $this->level) {
|
||||
continue;
|
||||
}
|
||||
$messages[] = $this->processRecord($record);
|
||||
}
|
||||
|
||||
if (!empty($messages)) {
|
||||
$messages = $this->getFormatter()->formatBatch($messages);
|
||||
self::$json['rows'] = array_merge(self::$json['rows'], $messages);
|
||||
$this->send();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function getDefaultFormatter()
|
||||
{
|
||||
return new ChromePHPFormatter();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates & sends header for a record
|
||||
*
|
||||
* @see sendHeader()
|
||||
* @see send()
|
||||
* @param array $record
|
||||
*/
|
||||
protected function write(array $record)
|
||||
{
|
||||
self::$json['rows'][] = $record['formatted'];
|
||||
|
||||
$this->send();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the log header
|
||||
*
|
||||
* @see sendHeader()
|
||||
*/
|
||||
protected function send()
|
||||
{
|
||||
if (self::$overflowed || !self::$sendHeaders) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!self::$initialized) {
|
||||
self::$initialized = true;
|
||||
|
||||
self::$sendHeaders = $this->headersAccepted();
|
||||
if (!self::$sendHeaders) {
|
||||
return;
|
||||
}
|
||||
|
||||
self::$json['request_uri'] = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
|
||||
}
|
||||
|
||||
$json = @json_encode(self::$json);
|
||||
$data = base64_encode(utf8_encode($json));
|
||||
if (strlen($data) > 240*1024) {
|
||||
self::$overflowed = true;
|
||||
|
||||
$record = array(
|
||||
'message' => 'Incomplete logs, chrome header size limit reached',
|
||||
'context' => array(),
|
||||
'level' => Logger::WARNING,
|
||||
'level_name' => Logger::getLevelName(Logger::WARNING),
|
||||
'channel' => 'monolog',
|
||||
'datetime' => new \DateTime(),
|
||||
'extra' => array(),
|
||||
);
|
||||
self::$json['rows'][count(self::$json['rows']) - 1] = $this->getFormatter()->format($record);
|
||||
$json = @json_encode(self::$json);
|
||||
$data = base64_encode(utf8_encode($json));
|
||||
}
|
||||
|
||||
if (trim($data) !== '') {
|
||||
$this->sendHeader(self::HEADER_NAME, $data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send header string to the client
|
||||
*
|
||||
* @param string $header
|
||||
* @param string $content
|
||||
*/
|
||||
protected function sendHeader($header, $content)
|
||||
{
|
||||
if (!headers_sent() && self::$sendHeaders) {
|
||||
header(sprintf('%s: %s', $header, $content));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies if the headers are accepted by the current user agent
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
protected function headersAccepted()
|
||||
{
|
||||
if (empty($_SERVER['HTTP_USER_AGENT'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return preg_match('{\bChrome/\d+[\.\d+]*\b}', $_SERVER['HTTP_USER_AGENT']);
|
||||
}
|
||||
|
||||
/**
|
||||
* BC getter for the sendHeaders property that has been made static
|
||||
*/
|
||||
public function __get($property)
|
||||
{
|
||||
if ('sendHeaders' !== $property) {
|
||||
throw new \InvalidArgumentException('Undefined property '.$property);
|
||||
}
|
||||
|
||||
return static::$sendHeaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* BC setter for the sendHeaders property that has been made static
|
||||
*/
|
||||
public function __set($property, $value)
|
||||
{
|
||||
if ('sendHeaders' !== $property) {
|
||||
throw new \InvalidArgumentException('Undefined property '.$property);
|
||||
}
|
||||
|
||||
static::$sendHeaders = $value;
|
||||
}
|
||||
}
|
||||
72
src/composer/vendor/monolog/monolog/src/Monolog/Handler/CouchDBHandler.php
vendored
Normal file
72
src/composer/vendor/monolog/monolog/src/Monolog/Handler/CouchDBHandler.php
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Monolog package.
|
||||
*
|
||||
* (c) 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 Monolog\Handler;
|
||||
|
||||
use Monolog\Formatter\JsonFormatter;
|
||||
use Monolog\Logger;
|
||||
|
||||
/**
|
||||
* CouchDB handler
|
||||
*
|
||||
* @author Markus Bachmann <markus.bachmann@bachi.biz>
|
||||
*/
|
||||
class CouchDBHandler extends AbstractProcessingHandler
|
||||
{
|
||||
private $options;
|
||||
|
||||
public function __construct(array $options = array(), $level = Logger::DEBUG, $bubble = true)
|
||||
{
|
||||
$this->options = array_merge(array(
|
||||
'host' => 'localhost',
|
||||
'port' => 5984,
|
||||
'dbname' => 'logger',
|
||||
'username' => null,
|
||||
'password' => null,
|
||||
), $options);
|
||||
|
||||
parent::__construct($level, $bubble);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function write(array $record)
|
||||
{
|
||||
$basicAuth = null;
|
||||
if ($this->options['username']) {
|
||||
$basicAuth = sprintf('%s:%s@', $this->options['username'], $this->options['password']);
|
||||
}
|
||||
|
||||
$url = 'http://'.$basicAuth.$this->options['host'].':'.$this->options['port'].'/'.$this->options['dbname'];
|
||||
$context = stream_context_create(array(
|
||||
'http' => array(
|
||||
'method' => 'POST',
|
||||
'content' => $record['formatted'],
|
||||
'ignore_errors' => true,
|
||||
'max_redirects' => 0,
|
||||
'header' => 'Content-type: application/json',
|
||||
)
|
||||
));
|
||||
|
||||
if (false === @file_get_contents($url, null, $context)) {
|
||||
throw new \RuntimeException(sprintf('Could not connect to %s', $url));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function getDefaultFormatter()
|
||||
{
|
||||
return new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, false);
|
||||
}
|
||||
}
|
||||
145
src/composer/vendor/monolog/monolog/src/Monolog/Handler/CubeHandler.php
vendored
Normal file
145
src/composer/vendor/monolog/monolog/src/Monolog/Handler/CubeHandler.php
vendored
Normal file
@@ -0,0 +1,145 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Monolog package.
|
||||
*
|
||||
* (c) 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 Monolog\Handler;
|
||||
|
||||
use Monolog\Logger;
|
||||
|
||||
/**
|
||||
* Logs to Cube.
|
||||
*
|
||||
* @link http://square.github.com/cube/
|
||||
* @author Wan Chen <kami@kamisama.me>
|
||||
*/
|
||||
class CubeHandler extends AbstractProcessingHandler
|
||||
{
|
||||
private $udpConnection = null;
|
||||
private $httpConnection = null;
|
||||
private $scheme = null;
|
||||
private $host = null;
|
||||
private $port = null;
|
||||
private $acceptedSchemes = array('http', 'udp');
|
||||
|
||||
/**
|
||||
* Create a Cube handler
|
||||
*
|
||||
* @throws UnexpectedValueException when given url is not a valid url.
|
||||
* A valid url must consists of three parts : protocol://host:port
|
||||
* Only valid protocol used by Cube are http and udp
|
||||
*/
|
||||
public function __construct($url, $level = Logger::DEBUG, $bubble = true)
|
||||
{
|
||||
$urlInfos = parse_url($url);
|
||||
|
||||
if (!isset($urlInfos['scheme']) || !isset($urlInfos['host']) || !isset($urlInfos['port'])) {
|
||||
throw new \UnexpectedValueException('URL "'.$url.'" is not valid');
|
||||
}
|
||||
|
||||
if (!in_array($urlInfos['scheme'], $this->acceptedSchemes)) {
|
||||
throw new \UnexpectedValueException(
|
||||
'Invalid protocol (' . $urlInfos['scheme'] . ').'
|
||||
. ' Valid options are ' . implode(', ', $this->acceptedSchemes));
|
||||
}
|
||||
|
||||
$this->scheme = $urlInfos['scheme'];
|
||||
$this->host = $urlInfos['host'];
|
||||
$this->port = $urlInfos['port'];
|
||||
|
||||
parent::__construct($level, $bubble);
|
||||
}
|
||||
|
||||
/**
|
||||
* Establish a connection to an UDP socket
|
||||
*
|
||||
* @throws LogicException when unable to connect to the socket
|
||||
*/
|
||||
protected function connectUdp()
|
||||
{
|
||||
if (!extension_loaded('sockets')) {
|
||||
throw new MissingExtensionException('The sockets extension is required to use udp URLs with the CubeHandler');
|
||||
}
|
||||
|
||||
$this->udpConnection = socket_create(AF_INET, SOCK_DGRAM, 0);
|
||||
if (!$this->udpConnection) {
|
||||
throw new \LogicException('Unable to create a socket');
|
||||
}
|
||||
|
||||
if (!socket_connect($this->udpConnection, $this->host, $this->port)) {
|
||||
throw new \LogicException('Unable to connect to the socket at ' . $this->host . ':' . $this->port);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Establish a connection to a http server
|
||||
*/
|
||||
protected function connectHttp()
|
||||
{
|
||||
if (!extension_loaded('curl')) {
|
||||
throw new \LogicException('The curl extension is needed to use http URLs with the CubeHandler');
|
||||
}
|
||||
|
||||
$this->httpConnection = curl_init('http://'.$this->host.':'.$this->port.'/1.0/event/put');
|
||||
|
||||
if (!$this->httpConnection) {
|
||||
throw new \LogicException('Unable to connect to ' . $this->host . ':' . $this->port);
|
||||
}
|
||||
|
||||
curl_setopt($this->httpConnection, CURLOPT_CUSTOMREQUEST, "POST");
|
||||
curl_setopt($this->httpConnection, CURLOPT_RETURNTRANSFER, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function write(array $record)
|
||||
{
|
||||
$date = $record['datetime'];
|
||||
|
||||
$data = array('time' => $date->format('Y-m-d\TH:i:s.uO'));
|
||||
unset($record['datetime']);
|
||||
|
||||
if (isset($record['context']['type'])) {
|
||||
$data['type'] = $record['context']['type'];
|
||||
unset($record['context']['type']);
|
||||
} else {
|
||||
$data['type'] = $record['channel'];
|
||||
}
|
||||
|
||||
$data['data'] = $record['context'];
|
||||
$data['data']['level'] = $record['level'];
|
||||
|
||||
$this->{'write'.$this->scheme}(json_encode($data));
|
||||
}
|
||||
|
||||
private function writeUdp($data)
|
||||
{
|
||||
if (!$this->udpConnection) {
|
||||
$this->connectUdp();
|
||||
}
|
||||
|
||||
socket_send($this->udpConnection, $data, strlen($data), 0);
|
||||
}
|
||||
|
||||
private function writeHttp($data)
|
||||
{
|
||||
if (!$this->httpConnection) {
|
||||
$this->connectHttp();
|
||||
}
|
||||
|
||||
curl_setopt($this->httpConnection, CURLOPT_POSTFIELDS, '['.$data.']');
|
||||
curl_setopt($this->httpConnection, CURLOPT_HTTPHEADER, array(
|
||||
'Content-Type: application/json',
|
||||
'Content-Length: ' . strlen('['.$data.']'))
|
||||
);
|
||||
|
||||
return curl_exec($this->httpConnection);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user