Showing
18 changed files
with
4853 additions
and
0 deletions
Too many changes to show.
To preserve performance only 18 of 18+ files are displayed.
| 1 | +{include file="common/head"/} | ||
| 2 | +<div class="admin-main layui-anim layui-anim-upbit"> | ||
| 3 | + <fieldset class="layui-elem-field layui-field-title"> | ||
| 4 | + <legend>{:$title}</legend> | ||
| 5 | + </fieldset> | ||
| 6 | + <div class="demoTable"> | ||
| 7 | + 商家: | ||
| 8 | + <div class="layui-input-inline"> | ||
| 9 | + <input class="layui-input" name="key" id="key" placeholder="{:lang('pleaseEnter')}店铺名称" autocomplete="off"> | ||
| 10 | + </div> | ||
| 11 | + 日期范围: | ||
| 12 | + <div class="layui-input-inline" > | ||
| 13 | + <input type="text" style = "width:300px"; class="layui-input" id="time" placeholder="默认为当天的充值情况"> | ||
| 14 | + </div> | ||
| 15 | + 商家来源: | ||
| 16 | + <div class="layui-input-inline layui-form"> | ||
| 17 | + <div class="layui-input-8"> | ||
| 18 | + <select name="class" id="channel" lay-filter="myselect"> | ||
| 19 | + <option value="-1">全部</option> | ||
| 20 | + <option value="1" selected>合作</option> | ||
| 21 | + <option value="2">推广</option> | ||
| 22 | + <option value="3">测试</option> | ||
| 23 | + </select> | ||
| 24 | + </div> | ||
| 25 | + </div> | ||
| 26 | + | ||
| 27 | + <button class="layui-btn" id="search" data-type="reload">查询统计</button> | ||
| 28 | + </div> | ||
| 29 | + <table class="layui-table" id="list" lay-filter="list"></table> | ||
| 30 | +</div> | ||
| 31 | +<script type="text/html" id="toolbarDemo"> | ||
| 32 | +</script> | ||
| 33 | +{include file="common/foot"/} | ||
| 34 | +<script> | ||
| 35 | + layui.use(['table','form','laydate'], function() { | ||
| 36 | + var table = layui.table,laydate = layui.laydate,$ = layui.jquery; | ||
| 37 | + console.log(layui); | ||
| 38 | + var tableIn = table.render({ | ||
| 39 | + elem: '#list', | ||
| 40 | + url: '{:url("getsellersmslist")}', | ||
| 41 | + method: 'post', | ||
| 42 | + title: '短信充值流水', | ||
| 43 | + page:true, | ||
| 44 | + toolbar: '#toolbarDemo', | ||
| 45 | + cols: [[ | ||
| 46 | + {field: 'id', title: '{:lang("id")}',width:70, fixed: true}, | ||
| 47 | + {field: 'sellername', align: 'center',title: '店铺名字'}, | ||
| 48 | + {field: 'package_name', title: '套餐'}, | ||
| 49 | + {field: 'total', title: '充值总数'}, | ||
| 50 | + {field: 'price', title: '金额'}, | ||
| 51 | + {field: 'channel', align: 'center', title: '充值渠道'}, | ||
| 52 | + {field: 'desc', align: 'center', title: '充值备注'}, | ||
| 53 | + {field: 'paystatus', align: 'center',title: '充值状态'}, | ||
| 54 | + {field: 'bdate', align: 'center',title: '购买时间', sort: true}, | ||
| 55 | + {field: 'cdate', align: 'center',title: '记录时间', sort: true}, | ||
| 56 | + ]], | ||
| 57 | + done: function(res, curr, count){ | ||
| 58 | + | ||
| 59 | + } | ||
| 60 | + ,id: 'testReload' | ||
| 61 | + ,page: true | ||
| 62 | + ,limit:10 | ||
| 63 | + }); | ||
| 64 | + | ||
| 65 | + //日期时间范围 | ||
| 66 | + laydate.render({ | ||
| 67 | + elem: '#time' | ||
| 68 | + ,type: 'datetime' | ||
| 69 | + ,range: true | ||
| 70 | + }); | ||
| 71 | + | ||
| 72 | + //搜索 | ||
| 73 | + $('#search').on('click', function() { | ||
| 74 | + //关键字 | ||
| 75 | + var key = $('#key').val(); | ||
| 76 | + | ||
| 77 | + var time = $('#time').val(); | ||
| 78 | + console.log(time); | ||
| 79 | + //商家来源 | ||
| 80 | + var channel = $('#channel').val(); | ||
| 81 | + console.log(channel); | ||
| 82 | + | ||
| 83 | + //传参 | ||
| 84 | + tableIn.reload({ page: {page: 1},where: {key: key,time: time,channel: channel}}); | ||
| 85 | + }); | ||
| 86 | + | ||
| 87 | + var $ = layui.$, active = { | ||
| 88 | + reload: function(){ | ||
| 89 | + var key = $('#key'); | ||
| 90 | + //执行重载 | ||
| 91 | + table.reload('testReload', { | ||
| 92 | + page: { | ||
| 93 | + curr: 1 //重新从第 1 页开始 | ||
| 94 | + } | ||
| 95 | + ,where: { | ||
| 96 | + key: { | ||
| 97 | + id: key.val() | ||
| 98 | + } | ||
| 99 | + } | ||
| 100 | + }); | ||
| 101 | + } | ||
| 102 | + }; | ||
| 103 | + }) | ||
| 104 | +</script> |
| 1 | +/* | ||
| 2 | +* @version: 2.0 | ||
| 3 | +* @Author: tomato | ||
| 4 | +* @Date: 2018-5-5 11:29:57 | ||
| 5 | +* @Last Modified by: tomato | ||
| 6 | +* @Last Modified time: 2018-5-26 18:08:43 | ||
| 7 | +*/ | ||
| 8 | +//多选下拉框 | ||
| 9 | +layui.define(['jquery', 'layer'], function(exports){ | ||
| 10 | + var MOD_NAME = 'selectM'; | ||
| 11 | + var $ = layui.jquery,layer=layui.layer; | ||
| 12 | + var obj = function(config){ | ||
| 13 | + this.disabledIndex =[]; | ||
| 14 | + //当前选中的值名数据 | ||
| 15 | + this.selected = []; | ||
| 16 | + //当前选中的值 | ||
| 17 | + this.values =[]; | ||
| 18 | + //当前选中的名称 | ||
| 19 | + this.names =[]; | ||
| 20 | + | ||
| 21 | + //初始化设置参数 | ||
| 22 | + this.config = { | ||
| 23 | + //选择器id或class | ||
| 24 | + elem: '', | ||
| 25 | + //候选项数据[{id:"1",name:"名称1",status:0},{id:"2",name:"名称2",status:1}] | ||
| 26 | + data: [], | ||
| 27 | + | ||
| 28 | + //默认选中值 | ||
| 29 | + selected: [], | ||
| 30 | + | ||
| 31 | + //空值项提示,支持将{max}替换为max | ||
| 32 | + tips: '请选择 最多 {max} 个', | ||
| 33 | + | ||
| 34 | + //最多选中个数,默认5 | ||
| 35 | + max : 5, | ||
| 36 | + | ||
| 37 | + //选择框宽度 | ||
| 38 | + width:null, | ||
| 39 | + | ||
| 40 | + //值验证,与lay-verify一致 | ||
| 41 | + verify: '', | ||
| 42 | + | ||
| 43 | + //input的name 不设置与选择器相同(去#.) | ||
| 44 | + name: '', | ||
| 45 | + | ||
| 46 | + //值的分隔符 | ||
| 47 | + delimiter: ',', | ||
| 48 | + | ||
| 49 | + //候选项数据的键名 status=0为禁用状态 | ||
| 50 | + field: {idName:'id',titleName:'name',statusName:'status'} | ||
| 51 | + } | ||
| 52 | + | ||
| 53 | + this.config = $.extend(this.config,config); | ||
| 54 | + //创建选项元素 | ||
| 55 | + this.createOption = function(){ | ||
| 56 | + var o=this,c=o.config,f=c.field,d = c.data; | ||
| 57 | + var s = c.selected; | ||
| 58 | + $E = $(c.elem); | ||
| 59 | + var tips = c.tips.replace('{max}',c.max); | ||
| 60 | + var inputName = c.name=='' ? c.elem.replace('#','').replace('.','') : c.name; | ||
| 61 | + var verify = c.verify=='' ? '' : 'lay-verify="'+c.verify+'" '; | ||
| 62 | + var html = ''; | ||
| 63 | + html += '<div class="layui-unselect layui-form-select">'; | ||
| 64 | + html += '<div class="layui-select-title">'; | ||
| 65 | + html += '<input '+verify+'name="'+inputName+'" type="text" readonly="" class="layui-input layui-unselect">'; | ||
| 66 | + html += '</div>'; | ||
| 67 | + html += '<div class="layui-input multiple">'; | ||
| 68 | + html += '</div>'; | ||
| 69 | + html += '<dl class="layui-anim layui-anim-upbit">'; | ||
| 70 | + html += '<dd lay-value="" class="layui-select-tips">'+tips+'</dd>'; | ||
| 71 | + for(var i=0;i<d.length;i++){ | ||
| 72 | + var disabled1='',disabled2=''; | ||
| 73 | + if(d[i][f.statusName]==0){ | ||
| 74 | + o.disabledIndex[d[i][f.idName]] = d[i][f.titleName]; | ||
| 75 | + disabled1 = d[i][f.statusName]==0 ? 'layui-disabled' : ''; | ||
| 76 | + disabled2 = d[i][f.statusName]==0 ? ' layui-checkbox-disbaled layui-disabled' : ''; | ||
| 77 | + } | ||
| 78 | + html +='<dd lay-value="'+d[i][f.idName]+'" class="'+disabled1+'">'; | ||
| 79 | + html += '<div class="layui-unselect layui-form-checkbox'+disabled2+'" lay-skin="primary">'; | ||
| 80 | + html += '<span>'+d[i][f.titleName]+'</span><i class="layui-icon"></i>'; | ||
| 81 | + html += '</div>'; | ||
| 82 | + html +='</dd>'; | ||
| 83 | + } | ||
| 84 | + html += '</dl>'; | ||
| 85 | + html += '</div>'; | ||
| 86 | + $E.html(html); | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + //设置选中值 | ||
| 90 | + this.set = function(selected){ | ||
| 91 | + var o=this,c=o.config; | ||
| 92 | + var s = typeof selected=='undefined' ? c.selected : selected; | ||
| 93 | + $E = $(c.elem); | ||
| 94 | + $E.find('.layui-form-checkbox').removeClass('layui-form-checked'); | ||
| 95 | + $E.find('dd').removeClass('layui-this'); | ||
| 96 | + //为默认选中值添加类名 | ||
| 97 | + var max = s.length>c.max ? c.max : s.length; | ||
| 98 | + for(var i=0;i<max;i++){ | ||
| 99 | + if(s[i] && !o.disabledIndex.hasOwnProperty(s[i])){ | ||
| 100 | + $E.find('dd[lay-value='+s[i]+']').addClass('layui-this'); | ||
| 101 | + } | ||
| 102 | + } | ||
| 103 | + $E.find('dd.layui-this').each(function(){ | ||
| 104 | + $(this).find('div').addClass('layui-form-checked'); | ||
| 105 | + }); | ||
| 106 | + o.setSelected(selected); | ||
| 107 | + } | ||
| 108 | + | ||
| 109 | + //设置选中值 每次点击操作后执行 | ||
| 110 | + this.setSelected = function(first){ | ||
| 111 | + var o=this,c=o.config,f=c.field; | ||
| 112 | + $E = $(c.elem); | ||
| 113 | + var values=[],names=[],selected = [],spans = []; | ||
| 114 | + var items = $E.find('dd.layui-this'); | ||
| 115 | + if(items.length==0){ | ||
| 116 | + var tips = c.tips.replace('{max}',c.max); | ||
| 117 | + spans.push('<span class="tips">'+tips+'</span>'); | ||
| 118 | + } | ||
| 119 | + else{ | ||
| 120 | + items.each(function(){ | ||
| 121 | + $this = $(this); | ||
| 122 | + var item ={}; | ||
| 123 | + var v = $this.attr('lay-value'); | ||
| 124 | + var n = $this.find('span').text(); | ||
| 125 | + item[f.idName] = v; | ||
| 126 | + item[f.titleName] = n; | ||
| 127 | + values.push(v); | ||
| 128 | + names.push(n); | ||
| 129 | + spans.push('<a href="javascript:;"><span lay-value="'+v+'">'+n+'</span><i class="layui-icon">ဆ</i></a>'); | ||
| 130 | + selected.push(item); | ||
| 131 | + }); | ||
| 132 | + } | ||
| 133 | + spans.push('<i class="layui-edge" style="pointer-events: none;"></i>'); | ||
| 134 | + $E.find('.multiple').html(spans.join('')); | ||
| 135 | + $E.find('.layui-select-title').find('input').each(function(){ | ||
| 136 | + if(typeof first=='undefined'){ | ||
| 137 | + this.defaultValue = values.join(c.delimiter); | ||
| 138 | + } | ||
| 139 | + this.value = values.join(c.delimiter); | ||
| 140 | + }); | ||
| 141 | + | ||
| 142 | + var h = $E.find('.multiple').height()+14; | ||
| 143 | + $E.find('.layui-form-select dl').css('top',h+'px'); | ||
| 144 | + o.values=values,o.names=names,o.selected = selected; | ||
| 145 | + } | ||
| 146 | + //ajax方式获取候选数据 | ||
| 147 | + this.getData = function(url){ | ||
| 148 | + var d; | ||
| 149 | + $.ajax({ | ||
| 150 | + url:url, | ||
| 151 | + dataType:'json', | ||
| 152 | + async:false, | ||
| 153 | + success:function(json){ | ||
| 154 | + d=json; | ||
| 155 | + }, | ||
| 156 | + error: function(){ | ||
| 157 | + console.error(MOD_NAME+' hint:候选数据ajax请求错误 '); | ||
| 158 | + d = false; | ||
| 159 | + } | ||
| 160 | + }); | ||
| 161 | + return d; | ||
| 162 | + } | ||
| 163 | + }; | ||
| 164 | + //渲染一个实例 | ||
| 165 | + obj.prototype.render = function(){ | ||
| 166 | + var o=this,c=o.config,f=c.field; | ||
| 167 | + $E = $(c.elem); | ||
| 168 | + if($E.length==0){ | ||
| 169 | + console.error(MOD_NAME+' hint:找不到容器 ' +c.elem); | ||
| 170 | + return false; | ||
| 171 | + } | ||
| 172 | + if(Object.prototype.toString.call(c.data)!='[object Array]'){ | ||
| 173 | + var data = o.getData(c.data); | ||
| 174 | + if(data===false){ | ||
| 175 | + console.error(MOD_NAME+' hint:缺少分类数据'); | ||
| 176 | + return false; | ||
| 177 | + } | ||
| 178 | + o.config.data = data; | ||
| 179 | + } | ||
| 180 | + | ||
| 181 | + //给容器添加一个类名 | ||
| 182 | + $E.addClass('lay-ext-mulitsel'); | ||
| 183 | + if(/^\d+$/.test(c.width)){ | ||
| 184 | + $E.css('width',c.width+'px'); | ||
| 185 | + } | ||
| 186 | + //添加专属的style | ||
| 187 | + if($('#lay-ext-mulitsel-style').length==0){ | ||
| 188 | + var style = '.lay-ext-mulitsel .layui-form-select dl dd div{margin-top:0px!important;}.lay-ext-mulitsel .layui-form-select dl dd.layui-this{background-color:#fff}.lay-ext-mulitsel .layui-input.multiple{line-height:auto;height:auto;padding:4px 10px 4px 10px;overflow:hidden;min-height:38px;margin-top:-38px;left:0;z-index:99;position:relative;background:#fff;}.lay-ext-mulitsel .layui-input.multiple a{padding:2px 5px;background:#5FB878;border-radius:2px;color:#fff;display:block;line-height:20px;height:20px;margin:2px 5px 2px 0;float:left;}.lay-ext-mulitsel .layui-input.multiple a i{margin-left:4px;font-size:14px;} .lay-ext-mulitsel .layui-input.multiple a i:hover{background-color:#009E94;border-radius:2px;}.lay-ext-mulitsel .danger{border-color:#FF5722!important}.lay-ext-mulitsel .tips{pointer-events: none;position: absolute;left: 10px;top: 10px;color:#757575;}'; | ||
| 189 | + $('<style id="lay-ext-mulitsel-style"></style>').text(style).appendTo($('head')); | ||
| 190 | + }; | ||
| 191 | + | ||
| 192 | + //创建选项 | ||
| 193 | + o.createOption(); | ||
| 194 | + //设置选中值 | ||
| 195 | + o.set(); | ||
| 196 | + | ||
| 197 | + //展开/收起选项 | ||
| 198 | + $E.on('click','.layui-select-title,.multiple,.multiple.layui-edge',function(e){ | ||
| 199 | + //隐藏其他实例显示的弹层 | ||
| 200 | + $('.lay-ext-mulitsel').not(c.elem).removeClass('layui-form-selected'); | ||
| 201 | + if($(c.elem).is('.layui-form-selected')){ | ||
| 202 | + $(c.elem).removeClass('layui-form-selected'); | ||
| 203 | + | ||
| 204 | + $(document).off('click',mEvent); | ||
| 205 | + } | ||
| 206 | + else{ | ||
| 207 | + $(c.elem).addClass('layui-form-selected'); | ||
| 208 | + | ||
| 209 | + $(document).on('click',mEvent=function(e){ | ||
| 210 | + if(e.target.id!==c.elem && e.target.className!=='layui-input multiple'){ | ||
| 211 | + $(c.elem).removeClass('layui-form-selected'); | ||
| 212 | + $(document).off('click',mEvent); | ||
| 213 | + } | ||
| 214 | + }); | ||
| 215 | + } | ||
| 216 | + }); | ||
| 217 | + | ||
| 218 | + //点击选项 | ||
| 219 | + $E.on('click','dd',function(e){ | ||
| 220 | + var _dd = $(this); | ||
| 221 | + if(_dd.hasClass('layui-disabled')){ | ||
| 222 | + return false; | ||
| 223 | + } | ||
| 224 | + //点 请选择 | ||
| 225 | + if(_dd.is('.layui-select-tips')){ | ||
| 226 | + _dd.siblings().removeClass('layui-this'); | ||
| 227 | + $(c.elem).find('.layui-form-checkbox').removeClass('layui-form-checked'); | ||
| 228 | + } | ||
| 229 | + //取消选中 | ||
| 230 | + else if(_dd.is('.layui-this')){ | ||
| 231 | + _dd.removeClass('layui-this'); | ||
| 232 | + _dd.find('.layui-form-checkbox').removeClass('layui-form-checked'); | ||
| 233 | + e.stopPropagation(); | ||
| 234 | + } | ||
| 235 | + //选中 | ||
| 236 | + else{ | ||
| 237 | + if(o.selected.length >= c.max){ | ||
| 238 | + $(c.elem+' .multiple').addClass('danger'); | ||
| 239 | + layer.tips('最多只能选择 '+c.max+' 个', c.elem+' .multiple', { | ||
| 240 | + tips: 3, | ||
| 241 | + time: 1000, | ||
| 242 | + end:function(){ | ||
| 243 | + $(c.elem+' .multiple').removeClass('danger'); | ||
| 244 | + } | ||
| 245 | + }); | ||
| 246 | + return false; | ||
| 247 | + } | ||
| 248 | + else{ | ||
| 249 | + _dd.addClass('layui-this'); | ||
| 250 | + _dd.find('.layui-form-checkbox').addClass('layui-form-checked'); | ||
| 251 | + e.stopPropagation(); | ||
| 252 | + } | ||
| 253 | + } | ||
| 254 | + | ||
| 255 | + o.setSelected(); | ||
| 256 | + }); | ||
| 257 | + | ||
| 258 | + //删除选项 | ||
| 259 | + $E.on('click','a i',function(e){ | ||
| 260 | + var _this = $(this).prev('span'); | ||
| 261 | + var v = _this.attr('lay-value'); | ||
| 262 | + if(v){ | ||
| 263 | + var _dd = $(c.elem).find('dd[lay-value='+v+']'); | ||
| 264 | + _dd.removeClass('layui-this'); | ||
| 265 | + _dd.find('.layui-form-checkbox').removeClass('layui-form-checked'); | ||
| 266 | + } | ||
| 267 | + o.setSelected(); | ||
| 268 | + _this.parent().remove(); | ||
| 269 | + e.stopPropagation(); | ||
| 270 | + | ||
| 271 | + }); | ||
| 272 | + | ||
| 273 | + //验证失败样式 | ||
| 274 | + $E.find('input').focus(function(){ | ||
| 275 | + $(c.elem+' .multiple').addClass('danger'); | ||
| 276 | + setTimeout(function(){ | ||
| 277 | + $(c.elem+' .multiple').removeClass('danger'); | ||
| 278 | + },3000); | ||
| 279 | + }); | ||
| 280 | + } | ||
| 281 | + | ||
| 282 | + //输出模块 | ||
| 283 | + exports(MOD_NAME, function (config) { | ||
| 284 | + var _this = new obj(config); | ||
| 285 | + _this.render(); | ||
| 286 | + return _this; | ||
| 287 | + }); | ||
| 288 | +}); |
| 1 | +/* | ||
| 2 | +* @version: 1.2 | ||
| 3 | +* @Author: tomato | ||
| 4 | +* @Date: 2018-4-24 22:56:00 | ||
| 5 | +* @Last Modified by: tomato | ||
| 6 | +* @Last Modified time: 2018-5-26 18:08:43 | ||
| 7 | +*/ | ||
| 8 | +//无限级下拉框 | ||
| 9 | +layui.define(['jquery', 'form'], function(exports){ | ||
| 10 | + var MOD_NAME = 'selectN'; | ||
| 11 | + var $ = layui.jquery; | ||
| 12 | + var form = layui.form; | ||
| 13 | + var obj = function(config){ | ||
| 14 | + //当前选中数据值名数据 | ||
| 15 | + this.selected =[]; | ||
| 16 | + //当前选中的值 | ||
| 17 | + this.values = []; | ||
| 18 | + //当前选中的名 | ||
| 19 | + this.names = []; | ||
| 20 | + //当前选中最后一个值 | ||
| 21 | + this.lastValue = ''; | ||
| 22 | + //当前选中最后一个值 | ||
| 23 | + this.lastName = ''; | ||
| 24 | + //是否已选 | ||
| 25 | + this.isSelected = false; | ||
| 26 | + //初始化配置 | ||
| 27 | + this.config = { | ||
| 28 | + //选择器id或class | ||
| 29 | + elem: '', | ||
| 30 | + //无限级分类数据 | ||
| 31 | + data: [], | ||
| 32 | + //默认选中值 | ||
| 33 | + selected: [], | ||
| 34 | + //空值项提示,可设置为数组['请选择省','请选择市','请选择县'] | ||
| 35 | + tips: '请选择', | ||
| 36 | + //是否允许搜索,可设置为数组[true,true,true] | ||
| 37 | + search:false, | ||
| 38 | + //选择项宽度,可设置为数组['80','90','100'] | ||
| 39 | + width:null, | ||
| 40 | + //为真只取最后一个值 | ||
| 41 | + last: false, | ||
| 42 | + //值验证,与lay-verify一致 | ||
| 43 | + verify: '', | ||
| 44 | + //事件过滤器,lay-filter名 | ||
| 45 | + filter: '', | ||
| 46 | + //input的name 不设置与选择器相同(去#.) | ||
| 47 | + name: '', | ||
| 48 | + //数据分隔符 | ||
| 49 | + delimiter: ',', | ||
| 50 | + //数据的键名 status=0为禁用状态 | ||
| 51 | + field:{idName:'id',titleName:'name',statusName:'status',childName:'children'}, | ||
| 52 | + //多表单区分 form.render(type, filter); 为class="layui-form" 所在元素的 lay-filter="" 的值 | ||
| 53 | + formFilter: null | ||
| 54 | + } | ||
| 55 | + | ||
| 56 | + //实例化配置 | ||
| 57 | + this.config = $.extend(this.config,config); | ||
| 58 | + | ||
| 59 | + //“请选择”文字 | ||
| 60 | + this.setTips = function(){ | ||
| 61 | + var o = this,c = o.config; | ||
| 62 | + if(Object.prototype.toString.call(c.tips)!='[object Array]'){ | ||
| 63 | + return c.tips; | ||
| 64 | + } | ||
| 65 | + else{ | ||
| 66 | + var i=$(c.elem).find('select').length; | ||
| 67 | + return c.tips.hasOwnProperty(i) ? c.tips[i] : '请选择'; | ||
| 68 | + } | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + //设置是否允许搜索 | ||
| 72 | + this.setSearch = function(){ | ||
| 73 | + var o = this,c = o.config; | ||
| 74 | + if(Object.prototype.toString.call(c.search)!='[object Array]'){ | ||
| 75 | + return c.search===true ? 'lay-search ' : ' '; | ||
| 76 | + } | ||
| 77 | + else{ | ||
| 78 | + var i=$(c.elem).find('select').length; | ||
| 79 | + if(c.search.hasOwnProperty(i)){ | ||
| 80 | + return c.search[i]===true ? 'lay-search ' : ' '; | ||
| 81 | + } | ||
| 82 | + } | ||
| 83 | + return ' '; | ||
| 84 | + } | ||
| 85 | + | ||
| 86 | + //设置是否允许搜索 | ||
| 87 | + this.setWidth = function(){ | ||
| 88 | + var o = this,c = o.config; | ||
| 89 | + if(Object.prototype.toString.call(c.width)!='[object Array]'){ | ||
| 90 | + return /^\d+$/.test(c.width) ? 'style="width:'+c.width+'px;" ' : ' '; | ||
| 91 | + } | ||
| 92 | + else{ | ||
| 93 | + var i=$(c.elem).find('select').length; | ||
| 94 | + if(c.width.hasOwnProperty(i)){ | ||
| 95 | + return /^\d+$/.test(c.width[i]) ? 'style="width:'+c.width[i]+'px;" ' : ' '; | ||
| 96 | + } | ||
| 97 | + } | ||
| 98 | + } | ||
| 99 | + | ||
| 100 | + //创建一个Select | ||
| 101 | + this.createSelect = function(optionData){ | ||
| 102 | + var o = this,c = o.config,f=c.field; | ||
| 103 | + var html = ''; | ||
| 104 | + html+= '<div class="layui-input-inline" '+o.setWidth()+'>'; | ||
| 105 | + html+= ' <select '+o.setSearch()+'lay-filter="'+c.filter+'">'; | ||
| 106 | + html+= ' <option value="">'+o.setTips()+'</option>'; | ||
| 107 | + for(var i=0;i<optionData.length;i++){ | ||
| 108 | + var disabled = optionData[i][f.statusName]==0 ? 'disabled="" ' : ''; | ||
| 109 | + html+= ' <option '+disabled+'value="'+optionData[i][f.idName]+'">'+optionData[i][f.titleName]+'</option>'; | ||
| 110 | + } | ||
| 111 | + html+= ' </select>'; | ||
| 112 | + html+= '</div>'; | ||
| 113 | + return html; | ||
| 114 | + }; | ||
| 115 | + | ||
| 116 | + //获取当前option的数据 | ||
| 117 | + this.getOptionData=function(catData,optionIndex){ | ||
| 118 | + var f = this.config.field; | ||
| 119 | + var item = catData; | ||
| 120 | + for(var i=0;i<optionIndex.length;i++){ | ||
| 121 | + if('undefined' == typeof item[optionIndex[i]]){ | ||
| 122 | + item = null; | ||
| 123 | + break; | ||
| 124 | + } | ||
| 125 | + else if('undefined' == typeof item[optionIndex[i]][f.childName]){ | ||
| 126 | + item = null; | ||
| 127 | + break; | ||
| 128 | + } | ||
| 129 | + else{ | ||
| 130 | + item = item[optionIndex[i]][f.childName]; | ||
| 131 | + } | ||
| 132 | + } | ||
| 133 | + return item; | ||
| 134 | + }; | ||
| 135 | + | ||
| 136 | + //初始化 | ||
| 137 | + this.set = function(selected){ | ||
| 138 | + var o = this,c = o.config; | ||
| 139 | + $E = $(c.elem); | ||
| 140 | + //创建顶级select | ||
| 141 | + var verify = c.verify=='' ? '' : 'lay-verify="'+c.verify+'" '; | ||
| 142 | + var html = '<div style="height:0px;width:0px;overflow:hidden"><input '+verify+'name="'+c.name+'"></div>'; | ||
| 143 | + html += o.createSelect(c.data); | ||
| 144 | + $E.html(html); | ||
| 145 | + selected = typeof selected=='undefined' ? c.selected : selected; | ||
| 146 | + var index=[]; | ||
| 147 | + for(var i=0;i<selected.length;i++){ | ||
| 148 | + //设置最后一个select的选中值 | ||
| 149 | + $E.find('select:last').val(selected[i]); | ||
| 150 | + //获取该选中值的索引 | ||
| 151 | + var lastIndex = $E.find('select:last').get(0).selectedIndex-1; | ||
| 152 | + index.push(lastIndex); | ||
| 153 | + //取出下级的选项值 | ||
| 154 | + var childItem = o.getOptionData(c.data,index); | ||
| 155 | + //下级选项值存在则创建select | ||
| 156 | + if(childItem){ | ||
| 157 | + var html = o.createSelect(childItem); | ||
| 158 | + $E.append(html); | ||
| 159 | + } | ||
| 160 | + } | ||
| 161 | + form.render('select',c.formFilter); | ||
| 162 | + o.getSelected(); | ||
| 163 | + }; | ||
| 164 | + | ||
| 165 | + //下拉事件 | ||
| 166 | + this.change = function(elem){ | ||
| 167 | + var o = this,c = o.config; | ||
| 168 | + var $thisItem = elem.parent(); | ||
| 169 | + //移除后面的select | ||
| 170 | + $thisItem.nextAll('div.layui-input-inline').remove(); | ||
| 171 | + var index=[]; | ||
| 172 | + //获取所有select,取出选中项的值和索引 | ||
| 173 | + $thisItem.parent().find('select').each(function(){ | ||
| 174 | + index.push($(this).get(0).selectedIndex-1); | ||
| 175 | + }); | ||
| 176 | + | ||
| 177 | + var childItem = o.getOptionData(c.data,index); | ||
| 178 | + if(childItem){ | ||
| 179 | + var html = o.createSelect(childItem); | ||
| 180 | + $thisItem.after(html); | ||
| 181 | + form.render('select',c.formFilter); | ||
| 182 | + } | ||
| 183 | + o.getSelected(); | ||
| 184 | + }; | ||
| 185 | + | ||
| 186 | + //获取所有值-数组 每次选择后执行 | ||
| 187 | + this.getSelected=function(){ | ||
| 188 | + var o = this,c = o.config; | ||
| 189 | + var values =[]; | ||
| 190 | + var names =[]; | ||
| 191 | + var selected =[]; | ||
| 192 | + $E = $(c.elem); | ||
| 193 | + $E.find('select').each(function(){ | ||
| 194 | + var item = {}; | ||
| 195 | + var v = $(this).val() | ||
| 196 | + var n = $(this).find('option:selected').text(); | ||
| 197 | + item.value = v; | ||
| 198 | + item.name = n; | ||
| 199 | + values.push(v); | ||
| 200 | + names.push(n); | ||
| 201 | + selected.push(item); | ||
| 202 | + }); | ||
| 203 | + o.selected =selected; | ||
| 204 | + o.values = values; | ||
| 205 | + o.names = names; | ||
| 206 | + o.lastValue = $E.find('select:last').val(); | ||
| 207 | + o.lastName = $E.find('option:selected:last').text(); | ||
| 208 | + | ||
| 209 | + o.isSelected = o.lastValue=='' ? false : true; | ||
| 210 | + var inputVal = c.last===true ? o.lastValue : o.values.join(c.delimiter); | ||
| 211 | + $E.find('input[name='+c.name+']').val(inputVal); | ||
| 212 | + }; | ||
| 213 | + //ajax方式获取候选数据 | ||
| 214 | + this.getData = function(url){ | ||
| 215 | + var d; | ||
| 216 | + $.ajax({ | ||
| 217 | + url:url, | ||
| 218 | + dataType:'json', | ||
| 219 | + async:false, | ||
| 220 | + success:function(json){ | ||
| 221 | + d=json; | ||
| 222 | + }, | ||
| 223 | + error: function(){ | ||
| 224 | + console.error(MOD_NAME+' hint:候选数据ajax请求错误 '); | ||
| 225 | + d = false; | ||
| 226 | + } | ||
| 227 | + }); | ||
| 228 | + return d; | ||
| 229 | + } | ||
| 230 | + | ||
| 231 | + | ||
| 232 | + }; | ||
| 233 | + | ||
| 234 | + //渲染一个实例 | ||
| 235 | + obj.prototype.render = function(){ | ||
| 236 | + var o=this,c=o.config; | ||
| 237 | + $E = $(c.elem); | ||
| 238 | + if($E.length==0){ | ||
| 239 | + console.error(MOD_NAME+' hint:找不到容器 '+c.elem); | ||
| 240 | + return false; | ||
| 241 | + } | ||
| 242 | + if(Object.prototype.toString.call(c.data)!='[object Array]'){ | ||
| 243 | + var data = o.getData(c.data); | ||
| 244 | + if(data===false){ | ||
| 245 | + console.error(MOD_NAME+' hint:缺少分类数据'); | ||
| 246 | + return false; | ||
| 247 | + } | ||
| 248 | + o.config.data = data; | ||
| 249 | + } | ||
| 250 | + | ||
| 251 | + c.filter = c.filter=='' ? c.elem.replace('#','').replace('.','') : c.filter; | ||
| 252 | + c.name = c.name=='' ? c.elem.replace('#','').replace('.','') : c.name; | ||
| 253 | + o.config = c; | ||
| 254 | + | ||
| 255 | + //初始化 | ||
| 256 | + o.set(); | ||
| 257 | + | ||
| 258 | + //监听下拉事件 | ||
| 259 | + form.on('select('+c.filter+')',function(data){ | ||
| 260 | + o.change($(data.elem)); | ||
| 261 | + }); | ||
| 262 | + //验证失败样式 | ||
| 263 | + $E.find('input[name='+c.name+']').focus(function(){ | ||
| 264 | + var t = $(c.elem).offset().top; | ||
| 265 | + $('html,body').scrollTop(t-200); | ||
| 266 | + $(c.elem).find('select:last').addClass('layui-form-danger'); | ||
| 267 | + setTimeout(function(){ | ||
| 268 | + $(c.elem).find('select:last').removeClass('layui-form-danger'); | ||
| 269 | + },3000); | ||
| 270 | + }); | ||
| 271 | + } | ||
| 272 | + | ||
| 273 | + //输出模块 | ||
| 274 | + exports(MOD_NAME, function (config) { | ||
| 275 | + var _this = new obj(config); | ||
| 276 | + _this.render(); | ||
| 277 | + return _this; | ||
| 278 | + }); | ||
| 279 | +}); |
vendor/Classes/PHPExcel.php
0 → 100644
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +/** PHPExcel root directory */ | ||
| 4 | +if (!defined('PHPEXCEL_ROOT')) { | ||
| 5 | + define('PHPEXCEL_ROOT', dirname(__FILE__) . '/'); | ||
| 6 | + require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php'); | ||
| 7 | +} | ||
| 8 | + | ||
| 9 | +/** | ||
| 10 | + * PHPExcel | ||
| 11 | + * | ||
| 12 | + * Copyright (c) 2006 - 2015 PHPExcel | ||
| 13 | + * | ||
| 14 | + * This library is free software; you can redistribute it and/or | ||
| 15 | + * modify it under the terms of the GNU Lesser General Public | ||
| 16 | + * License as published by the Free Software Foundation; either | ||
| 17 | + * version 2.1 of the License, or (at your option) any later version. | ||
| 18 | + * | ||
| 19 | + * This library is distributed in the hope that it will be useful, | ||
| 20 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 21 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 22 | + * Lesser General Public License for more details. | ||
| 23 | + * | ||
| 24 | + * You should have received a copy of the GNU Lesser General Public | ||
| 25 | + * License along with this library; if not, write to the Free Software | ||
| 26 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 27 | + * | ||
| 28 | + * @category PHPExcel | ||
| 29 | + * @package PHPExcel | ||
| 30 | + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) | ||
| 31 | + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL | ||
| 32 | + * @version ##VERSION##, ##DATE## | ||
| 33 | + */ | ||
| 34 | +class PHPExcel | ||
| 35 | +{ | ||
| 36 | + /** | ||
| 37 | + * Unique ID | ||
| 38 | + * | ||
| 39 | + * @var string | ||
| 40 | + */ | ||
| 41 | + private $uniqueID; | ||
| 42 | + | ||
| 43 | + /** | ||
| 44 | + * Document properties | ||
| 45 | + * | ||
| 46 | + * @var PHPExcel_DocumentProperties | ||
| 47 | + */ | ||
| 48 | + private $properties; | ||
| 49 | + | ||
| 50 | + /** | ||
| 51 | + * Document security | ||
| 52 | + * | ||
| 53 | + * @var PHPExcel_DocumentSecurity | ||
| 54 | + */ | ||
| 55 | + private $security; | ||
| 56 | + | ||
| 57 | + /** | ||
| 58 | + * Collection of Worksheet objects | ||
| 59 | + * | ||
| 60 | + * @var PHPExcel_Worksheet[] | ||
| 61 | + */ | ||
| 62 | + private $workSheetCollection = array(); | ||
| 63 | + | ||
| 64 | + /** | ||
| 65 | + * Calculation Engine | ||
| 66 | + * | ||
| 67 | + * @var PHPExcel_Calculation | ||
| 68 | + */ | ||
| 69 | + private $calculationEngine; | ||
| 70 | + | ||
| 71 | + /** | ||
| 72 | + * Active sheet index | ||
| 73 | + * | ||
| 74 | + * @var integer | ||
| 75 | + */ | ||
| 76 | + private $activeSheetIndex = 0; | ||
| 77 | + | ||
| 78 | + /** | ||
| 79 | + * Named ranges | ||
| 80 | + * | ||
| 81 | + * @var PHPExcel_NamedRange[] | ||
| 82 | + */ | ||
| 83 | + private $namedRanges = array(); | ||
| 84 | + | ||
| 85 | + /** | ||
| 86 | + * CellXf supervisor | ||
| 87 | + * | ||
| 88 | + * @var PHPExcel_Style | ||
| 89 | + */ | ||
| 90 | + private $cellXfSupervisor; | ||
| 91 | + | ||
| 92 | + /** | ||
| 93 | + * CellXf collection | ||
| 94 | + * | ||
| 95 | + * @var PHPExcel_Style[] | ||
| 96 | + */ | ||
| 97 | + private $cellXfCollection = array(); | ||
| 98 | + | ||
| 99 | + /** | ||
| 100 | + * CellStyleXf collection | ||
| 101 | + * | ||
| 102 | + * @var PHPExcel_Style[] | ||
| 103 | + */ | ||
| 104 | + private $cellStyleXfCollection = array(); | ||
| 105 | + | ||
| 106 | + /** | ||
| 107 | + * hasMacros : this workbook have macros ? | ||
| 108 | + * | ||
| 109 | + * @var bool | ||
| 110 | + */ | ||
| 111 | + private $hasMacros = false; | ||
| 112 | + | ||
| 113 | + /** | ||
| 114 | + * macrosCode : all macros code (the vbaProject.bin file, this include form, code, etc.), null if no macro | ||
| 115 | + * | ||
| 116 | + * @var binary | ||
| 117 | + */ | ||
| 118 | + private $macrosCode; | ||
| 119 | + /** | ||
| 120 | + * macrosCertificate : if macros are signed, contains vbaProjectSignature.bin file, null if not signed | ||
| 121 | + * | ||
| 122 | + * @var binary | ||
| 123 | + */ | ||
| 124 | + private $macrosCertificate; | ||
| 125 | + | ||
| 126 | + /** | ||
| 127 | + * ribbonXMLData : null if workbook is'nt Excel 2007 or not contain a customized UI | ||
| 128 | + * | ||
| 129 | + * @var null|string | ||
| 130 | + */ | ||
| 131 | + private $ribbonXMLData; | ||
| 132 | + | ||
| 133 | + /** | ||
| 134 | + * ribbonBinObjects : null if workbook is'nt Excel 2007 or not contain embedded objects (picture(s)) for Ribbon Elements | ||
| 135 | + * ignored if $ribbonXMLData is null | ||
| 136 | + * | ||
| 137 | + * @var null|array | ||
| 138 | + */ | ||
| 139 | + private $ribbonBinObjects; | ||
| 140 | + | ||
| 141 | + /** | ||
| 142 | + * The workbook has macros ? | ||
| 143 | + * | ||
| 144 | + * @return boolean true if workbook has macros, false if not | ||
| 145 | + */ | ||
| 146 | + public function hasMacros() | ||
| 147 | + { | ||
| 148 | + return $this->hasMacros; | ||
| 149 | + } | ||
| 150 | + | ||
| 151 | + /** | ||
| 152 | + * Define if a workbook has macros | ||
| 153 | + * | ||
| 154 | + * @param boolean $hasMacros true|false | ||
| 155 | + */ | ||
| 156 | + public function setHasMacros($hasMacros = false) | ||
| 157 | + { | ||
| 158 | + $this->hasMacros = (bool) $hasMacros; | ||
| 159 | + } | ||
| 160 | + | ||
| 161 | + /** | ||
| 162 | + * Set the macros code | ||
| 163 | + * | ||
| 164 | + * @param string $MacrosCode string|null | ||
| 165 | + */ | ||
| 166 | + public function setMacrosCode($MacrosCode = null) | ||
| 167 | + { | ||
| 168 | + $this->macrosCode=$MacrosCode; | ||
| 169 | + $this->setHasMacros(!is_null($MacrosCode)); | ||
| 170 | + } | ||
| 171 | + | ||
| 172 | + /** | ||
| 173 | + * Return the macros code | ||
| 174 | + * | ||
| 175 | + * @return string|null | ||
| 176 | + */ | ||
| 177 | + public function getMacrosCode() | ||
| 178 | + { | ||
| 179 | + return $this->macrosCode; | ||
| 180 | + } | ||
| 181 | + | ||
| 182 | + /** | ||
| 183 | + * Set the macros certificate | ||
| 184 | + * | ||
| 185 | + * @param string|null $Certificate | ||
| 186 | + */ | ||
| 187 | + public function setMacrosCertificate($Certificate = null) | ||
| 188 | + { | ||
| 189 | + $this->macrosCertificate=$Certificate; | ||
| 190 | + } | ||
| 191 | + | ||
| 192 | + /** | ||
| 193 | + * Is the project signed ? | ||
| 194 | + * | ||
| 195 | + * @return boolean true|false | ||
| 196 | + */ | ||
| 197 | + public function hasMacrosCertificate() | ||
| 198 | + { | ||
| 199 | + return !is_null($this->macrosCertificate); | ||
| 200 | + } | ||
| 201 | + | ||
| 202 | + /** | ||
| 203 | + * Return the macros certificate | ||
| 204 | + * | ||
| 205 | + * @return string|null | ||
| 206 | + */ | ||
| 207 | + public function getMacrosCertificate() | ||
| 208 | + { | ||
| 209 | + return $this->macrosCertificate; | ||
| 210 | + } | ||
| 211 | + | ||
| 212 | + /** | ||
| 213 | + * Remove all macros, certificate from spreadsheet | ||
| 214 | + * | ||
| 215 | + */ | ||
| 216 | + public function discardMacros() | ||
| 217 | + { | ||
| 218 | + $this->hasMacros=false; | ||
| 219 | + $this->macrosCode=null; | ||
| 220 | + $this->macrosCertificate=null; | ||
| 221 | + } | ||
| 222 | + | ||
| 223 | + /** | ||
| 224 | + * set ribbon XML data | ||
| 225 | + * | ||
| 226 | + */ | ||
| 227 | + public function setRibbonXMLData($Target = null, $XMLData = null) | ||
| 228 | + { | ||
| 229 | + if (!is_null($Target) && !is_null($XMLData)) { | ||
| 230 | + $this->ribbonXMLData = array('target' => $Target, 'data' => $XMLData); | ||
| 231 | + } else { | ||
| 232 | + $this->ribbonXMLData = null; | ||
| 233 | + } | ||
| 234 | + } | ||
| 235 | + | ||
| 236 | + /** | ||
| 237 | + * retrieve ribbon XML Data | ||
| 238 | + * | ||
| 239 | + * return string|null|array | ||
| 240 | + */ | ||
| 241 | + public function getRibbonXMLData($What = 'all') //we need some constants here... | ||
| 242 | + { | ||
| 243 | + $ReturnData = null; | ||
| 244 | + $What = strtolower($What); | ||
| 245 | + switch ($What){ | ||
| 246 | + case 'all': | ||
| 247 | + $ReturnData = $this->ribbonXMLData; | ||
| 248 | + break; | ||
| 249 | + case 'target': | ||
| 250 | + case 'data': | ||
| 251 | + if (is_array($this->ribbonXMLData) && array_key_exists($What, $this->ribbonXMLData)) { | ||
| 252 | + $ReturnData = $this->ribbonXMLData[$What]; | ||
| 253 | + } | ||
| 254 | + break; | ||
| 255 | + } | ||
| 256 | + | ||
| 257 | + return $ReturnData; | ||
| 258 | + } | ||
| 259 | + | ||
| 260 | + /** | ||
| 261 | + * store binaries ribbon objects (pictures) | ||
| 262 | + * | ||
| 263 | + */ | ||
| 264 | + public function setRibbonBinObjects($BinObjectsNames = null, $BinObjectsData = null) | ||
| 265 | + { | ||
| 266 | + if (!is_null($BinObjectsNames) && !is_null($BinObjectsData)) { | ||
| 267 | + $this->ribbonBinObjects = array('names' => $BinObjectsNames, 'data' => $BinObjectsData); | ||
| 268 | + } else { | ||
| 269 | + $this->ribbonBinObjects = null; | ||
| 270 | + } | ||
| 271 | + } | ||
| 272 | + /** | ||
| 273 | + * return the extension of a filename. Internal use for a array_map callback (php<5.3 don't like lambda function) | ||
| 274 | + * | ||
| 275 | + */ | ||
| 276 | + private function getExtensionOnly($ThePath) | ||
| 277 | + { | ||
| 278 | + return pathinfo($ThePath, PATHINFO_EXTENSION); | ||
| 279 | + } | ||
| 280 | + | ||
| 281 | + /** | ||
| 282 | + * retrieve Binaries Ribbon Objects | ||
| 283 | + * | ||
| 284 | + */ | ||
| 285 | + public function getRibbonBinObjects($What = 'all') | ||
| 286 | + { | ||
| 287 | + $ReturnData = null; | ||
| 288 | + $What = strtolower($What); | ||
| 289 | + switch($What) { | ||
| 290 | + case 'all': | ||
| 291 | + return $this->ribbonBinObjects; | ||
| 292 | + break; | ||
| 293 | + case 'names': | ||
| 294 | + case 'data': | ||
| 295 | + if (is_array($this->ribbonBinObjects) && array_key_exists($What, $this->ribbonBinObjects)) { | ||
| 296 | + $ReturnData=$this->ribbonBinObjects[$What]; | ||
| 297 | + } | ||
| 298 | + break; | ||
| 299 | + case 'types': | ||
| 300 | + if (is_array($this->ribbonBinObjects) && | ||
| 301 | + array_key_exists('data', $this->ribbonBinObjects) && is_array($this->ribbonBinObjects['data'])) { | ||
| 302 | + $tmpTypes=array_keys($this->ribbonBinObjects['data']); | ||
| 303 | + $ReturnData = array_unique(array_map(array($this, 'getExtensionOnly'), $tmpTypes)); | ||
| 304 | + } else { | ||
| 305 | + $ReturnData=array(); // the caller want an array... not null if empty | ||
| 306 | + } | ||
| 307 | + break; | ||
| 308 | + } | ||
| 309 | + return $ReturnData; | ||
| 310 | + } | ||
| 311 | + | ||
| 312 | + /** | ||
| 313 | + * This workbook have a custom UI ? | ||
| 314 | + * | ||
| 315 | + * @return boolean true|false | ||
| 316 | + */ | ||
| 317 | + public function hasRibbon() | ||
| 318 | + { | ||
| 319 | + return !is_null($this->ribbonXMLData); | ||
| 320 | + } | ||
| 321 | + | ||
| 322 | + /** | ||
| 323 | + * This workbook have additionnal object for the ribbon ? | ||
| 324 | + * | ||
| 325 | + * @return boolean true|false | ||
| 326 | + */ | ||
| 327 | + public function hasRibbonBinObjects() | ||
| 328 | + { | ||
| 329 | + return !is_null($this->ribbonBinObjects); | ||
| 330 | + } | ||
| 331 | + | ||
| 332 | + /** | ||
| 333 | + * Check if a sheet with a specified code name already exists | ||
| 334 | + * | ||
| 335 | + * @param string $pSheetCodeName Name of the worksheet to check | ||
| 336 | + * @return boolean | ||
| 337 | + */ | ||
| 338 | + public function sheetCodeNameExists($pSheetCodeName) | ||
| 339 | + { | ||
| 340 | + return ($this->getSheetByCodeName($pSheetCodeName) !== null); | ||
| 341 | + } | ||
| 342 | + | ||
| 343 | + /** | ||
| 344 | + * Get sheet by code name. Warning : sheet don't have always a code name ! | ||
| 345 | + * | ||
| 346 | + * @param string $pName Sheet name | ||
| 347 | + * @return PHPExcel_Worksheet | ||
| 348 | + */ | ||
| 349 | + public function getSheetByCodeName($pName = '') | ||
| 350 | + { | ||
| 351 | + $worksheetCount = count($this->workSheetCollection); | ||
| 352 | + for ($i = 0; $i < $worksheetCount; ++$i) { | ||
| 353 | + if ($this->workSheetCollection[$i]->getCodeName() == $pName) { | ||
| 354 | + return $this->workSheetCollection[$i]; | ||
| 355 | + } | ||
| 356 | + } | ||
| 357 | + | ||
| 358 | + return null; | ||
| 359 | + } | ||
| 360 | + | ||
| 361 | + /** | ||
| 362 | + * Create a new PHPExcel with one Worksheet | ||
| 363 | + */ | ||
| 364 | + public function __construct() | ||
| 365 | + { | ||
| 366 | + $this->uniqueID = uniqid(); | ||
| 367 | + $this->calculationEngine = new PHPExcel_Calculation($this); | ||
| 368 | + | ||
| 369 | + // Initialise worksheet collection and add one worksheet | ||
| 370 | + $this->workSheetCollection = array(); | ||
| 371 | + $this->workSheetCollection[] = new PHPExcel_Worksheet($this); | ||
| 372 | + $this->activeSheetIndex = 0; | ||
| 373 | + | ||
| 374 | + // Create document properties | ||
| 375 | + $this->properties = new PHPExcel_DocumentProperties(); | ||
| 376 | + | ||
| 377 | + // Create document security | ||
| 378 | + $this->security = new PHPExcel_DocumentSecurity(); | ||
| 379 | + | ||
| 380 | + // Set named ranges | ||
| 381 | + $this->namedRanges = array(); | ||
| 382 | + | ||
| 383 | + // Create the cellXf supervisor | ||
| 384 | + $this->cellXfSupervisor = new PHPExcel_Style(true); | ||
| 385 | + $this->cellXfSupervisor->bindParent($this); | ||
| 386 | + | ||
| 387 | + // Create the default style | ||
| 388 | + $this->addCellXf(new PHPExcel_Style); | ||
| 389 | + $this->addCellStyleXf(new PHPExcel_Style); | ||
| 390 | + } | ||
| 391 | + | ||
| 392 | + /** | ||
| 393 | + * Code to execute when this worksheet is unset() | ||
| 394 | + * | ||
| 395 | + */ | ||
| 396 | + public function __destruct() | ||
| 397 | + { | ||
| 398 | + $this->calculationEngine = null; | ||
| 399 | + $this->disconnectWorksheets(); | ||
| 400 | + } | ||
| 401 | + | ||
| 402 | + /** | ||
| 403 | + * Disconnect all worksheets from this PHPExcel workbook object, | ||
| 404 | + * typically so that the PHPExcel object can be unset | ||
| 405 | + * | ||
| 406 | + */ | ||
| 407 | + public function disconnectWorksheets() | ||
| 408 | + { | ||
| 409 | + $worksheet = null; | ||
| 410 | + foreach ($this->workSheetCollection as $k => &$worksheet) { | ||
| 411 | + $worksheet->disconnectCells(); | ||
| 412 | + $this->workSheetCollection[$k] = null; | ||
| 413 | + } | ||
| 414 | + unset($worksheet); | ||
| 415 | + $this->workSheetCollection = array(); | ||
| 416 | + } | ||
| 417 | + | ||
| 418 | + /** | ||
| 419 | + * Return the calculation engine for this worksheet | ||
| 420 | + * | ||
| 421 | + * @return PHPExcel_Calculation | ||
| 422 | + */ | ||
| 423 | + public function getCalculationEngine() | ||
| 424 | + { | ||
| 425 | + return $this->calculationEngine; | ||
| 426 | + } // function getCellCacheController() | ||
| 427 | + | ||
| 428 | + /** | ||
| 429 | + * Get properties | ||
| 430 | + * | ||
| 431 | + * @return PHPExcel_DocumentProperties | ||
| 432 | + */ | ||
| 433 | + public function getProperties() | ||
| 434 | + { | ||
| 435 | + return $this->properties; | ||
| 436 | + } | ||
| 437 | + | ||
| 438 | + /** | ||
| 439 | + * Set properties | ||
| 440 | + * | ||
| 441 | + * @param PHPExcel_DocumentProperties $pValue | ||
| 442 | + */ | ||
| 443 | + public function setProperties(PHPExcel_DocumentProperties $pValue) | ||
| 444 | + { | ||
| 445 | + $this->properties = $pValue; | ||
| 446 | + } | ||
| 447 | + | ||
| 448 | + /** | ||
| 449 | + * Get security | ||
| 450 | + * | ||
| 451 | + * @return PHPExcel_DocumentSecurity | ||
| 452 | + */ | ||
| 453 | + public function getSecurity() | ||
| 454 | + { | ||
| 455 | + return $this->security; | ||
| 456 | + } | ||
| 457 | + | ||
| 458 | + /** | ||
| 459 | + * Set security | ||
| 460 | + * | ||
| 461 | + * @param PHPExcel_DocumentSecurity $pValue | ||
| 462 | + */ | ||
| 463 | + public function setSecurity(PHPExcel_DocumentSecurity $pValue) | ||
| 464 | + { | ||
| 465 | + $this->security = $pValue; | ||
| 466 | + } | ||
| 467 | + | ||
| 468 | + /** | ||
| 469 | + * Get active sheet | ||
| 470 | + * | ||
| 471 | + * @return PHPExcel_Worksheet | ||
| 472 | + * | ||
| 473 | + * @throws PHPExcel_Exception | ||
| 474 | + */ | ||
| 475 | + public function getActiveSheet() | ||
| 476 | + { | ||
| 477 | + return $this->getSheet($this->activeSheetIndex); | ||
| 478 | + } | ||
| 479 | + | ||
| 480 | + /** | ||
| 481 | + * Create sheet and add it to this workbook | ||
| 482 | + * | ||
| 483 | + * @param int|null $iSheetIndex Index where sheet should go (0,1,..., or null for last) | ||
| 484 | + * @return PHPExcel_Worksheet | ||
| 485 | + * @throws PHPExcel_Exception | ||
| 486 | + */ | ||
| 487 | + public function createSheet($iSheetIndex = null) | ||
| 488 | + { | ||
| 489 | + $newSheet = new PHPExcel_Worksheet($this); | ||
| 490 | + $this->addSheet($newSheet, $iSheetIndex); | ||
| 491 | + return $newSheet; | ||
| 492 | + } | ||
| 493 | + | ||
| 494 | + /** | ||
| 495 | + * Check if a sheet with a specified name already exists | ||
| 496 | + * | ||
| 497 | + * @param string $pSheetName Name of the worksheet to check | ||
| 498 | + * @return boolean | ||
| 499 | + */ | ||
| 500 | + public function sheetNameExists($pSheetName) | ||
| 501 | + { | ||
| 502 | + return ($this->getSheetByName($pSheetName) !== null); | ||
| 503 | + } | ||
| 504 | + | ||
| 505 | + /** | ||
| 506 | + * Add sheet | ||
| 507 | + * | ||
| 508 | + * @param PHPExcel_Worksheet $pSheet | ||
| 509 | + * @param int|null $iSheetIndex Index where sheet should go (0,1,..., or null for last) | ||
| 510 | + * @return PHPExcel_Worksheet | ||
| 511 | + * @throws PHPExcel_Exception | ||
| 512 | + */ | ||
| 513 | + public function addSheet(PHPExcel_Worksheet $pSheet, $iSheetIndex = null) | ||
| 514 | + { | ||
| 515 | + if ($this->sheetNameExists($pSheet->getTitle())) { | ||
| 516 | + throw new PHPExcel_Exception( | ||
| 517 | + "Workbook already contains a worksheet named '{$pSheet->getTitle()}'. Rename this worksheet first." | ||
| 518 | + ); | ||
| 519 | + } | ||
| 520 | + | ||
| 521 | + if ($iSheetIndex === null) { | ||
| 522 | + if ($this->activeSheetIndex < 0) { | ||
| 523 | + $this->activeSheetIndex = 0; | ||
| 524 | + } | ||
| 525 | + $this->workSheetCollection[] = $pSheet; | ||
| 526 | + } else { | ||
| 527 | + // Insert the sheet at the requested index | ||
| 528 | + array_splice( | ||
| 529 | + $this->workSheetCollection, | ||
| 530 | + $iSheetIndex, | ||
| 531 | + 0, | ||
| 532 | + array($pSheet) | ||
| 533 | + ); | ||
| 534 | + | ||
| 535 | + // Adjust active sheet index if necessary | ||
| 536 | + if ($this->activeSheetIndex >= $iSheetIndex) { | ||
| 537 | + ++$this->activeSheetIndex; | ||
| 538 | + } | ||
| 539 | + } | ||
| 540 | + | ||
| 541 | + if ($pSheet->getParent() === null) { | ||
| 542 | + $pSheet->rebindParent($this); | ||
| 543 | + } | ||
| 544 | + | ||
| 545 | + return $pSheet; | ||
| 546 | + } | ||
| 547 | + | ||
| 548 | + /** | ||
| 549 | + * Remove sheet by index | ||
| 550 | + * | ||
| 551 | + * @param int $pIndex Active sheet index | ||
| 552 | + * @throws PHPExcel_Exception | ||
| 553 | + */ | ||
| 554 | + public function removeSheetByIndex($pIndex = 0) | ||
| 555 | + { | ||
| 556 | + | ||
| 557 | + $numSheets = count($this->workSheetCollection); | ||
| 558 | + if ($pIndex > $numSheets - 1) { | ||
| 559 | + throw new PHPExcel_Exception( | ||
| 560 | + "You tried to remove a sheet by the out of bounds index: {$pIndex}. The actual number of sheets is {$numSheets}." | ||
| 561 | + ); | ||
| 562 | + } else { | ||
| 563 | + array_splice($this->workSheetCollection, $pIndex, 1); | ||
| 564 | + } | ||
| 565 | + // Adjust active sheet index if necessary | ||
| 566 | + if (($this->activeSheetIndex >= $pIndex) && | ||
| 567 | + ($pIndex > count($this->workSheetCollection) - 1)) { | ||
| 568 | + --$this->activeSheetIndex; | ||
| 569 | + } | ||
| 570 | + | ||
| 571 | + } | ||
| 572 | + | ||
| 573 | + /** | ||
| 574 | + * Get sheet by index | ||
| 575 | + * | ||
| 576 | + * @param int $pIndex Sheet index | ||
| 577 | + * @return PHPExcel_Worksheet | ||
| 578 | + * @throws PHPExcel_Exception | ||
| 579 | + */ | ||
| 580 | + public function getSheet($pIndex = 0) | ||
| 581 | + { | ||
| 582 | + if (!isset($this->workSheetCollection[$pIndex])) { | ||
| 583 | + $numSheets = $this->getSheetCount(); | ||
| 584 | + throw new PHPExcel_Exception( | ||
| 585 | + "Your requested sheet index: {$pIndex} is out of bounds. The actual number of sheets is {$numSheets}." | ||
| 586 | + ); | ||
| 587 | + } | ||
| 588 | + | ||
| 589 | + return $this->workSheetCollection[$pIndex]; | ||
| 590 | + } | ||
| 591 | + | ||
| 592 | + /** | ||
| 593 | + * Get all sheets | ||
| 594 | + * | ||
| 595 | + * @return PHPExcel_Worksheet[] | ||
| 596 | + */ | ||
| 597 | + public function getAllSheets() | ||
| 598 | + { | ||
| 599 | + return $this->workSheetCollection; | ||
| 600 | + } | ||
| 601 | + | ||
| 602 | + /** | ||
| 603 | + * Get sheet by name | ||
| 604 | + * | ||
| 605 | + * @param string $pName Sheet name | ||
| 606 | + * @return PHPExcel_Worksheet | ||
| 607 | + */ | ||
| 608 | + public function getSheetByName($pName = '') | ||
| 609 | + { | ||
| 610 | + $worksheetCount = count($this->workSheetCollection); | ||
| 611 | + for ($i = 0; $i < $worksheetCount; ++$i) { | ||
| 612 | + if ($this->workSheetCollection[$i]->getTitle() === $pName) { | ||
| 613 | + return $this->workSheetCollection[$i]; | ||
| 614 | + } | ||
| 615 | + } | ||
| 616 | + | ||
| 617 | + return null; | ||
| 618 | + } | ||
| 619 | + | ||
| 620 | + /** | ||
| 621 | + * Get index for sheet | ||
| 622 | + * | ||
| 623 | + * @param PHPExcel_Worksheet $pSheet | ||
| 624 | + * @return int Sheet index | ||
| 625 | + * @throws PHPExcel_Exception | ||
| 626 | + */ | ||
| 627 | + public function getIndex(PHPExcel_Worksheet $pSheet) | ||
| 628 | + { | ||
| 629 | + foreach ($this->workSheetCollection as $key => $value) { | ||
| 630 | + if ($value->getHashCode() == $pSheet->getHashCode()) { | ||
| 631 | + return $key; | ||
| 632 | + } | ||
| 633 | + } | ||
| 634 | + | ||
| 635 | + throw new PHPExcel_Exception("Sheet does not exist."); | ||
| 636 | + } | ||
| 637 | + | ||
| 638 | + /** | ||
| 639 | + * Set index for sheet by sheet name. | ||
| 640 | + * | ||
| 641 | + * @param string $sheetName Sheet name to modify index for | ||
| 642 | + * @param int $newIndex New index for the sheet | ||
| 643 | + * @return int New sheet index | ||
| 644 | + * @throws PHPExcel_Exception | ||
| 645 | + */ | ||
| 646 | + public function setIndexByName($sheetName, $newIndex) | ||
| 647 | + { | ||
| 648 | + $oldIndex = $this->getIndex($this->getSheetByName($sheetName)); | ||
| 649 | + $pSheet = array_splice( | ||
| 650 | + $this->workSheetCollection, | ||
| 651 | + $oldIndex, | ||
| 652 | + 1 | ||
| 653 | + ); | ||
| 654 | + array_splice( | ||
| 655 | + $this->workSheetCollection, | ||
| 656 | + $newIndex, | ||
| 657 | + 0, | ||
| 658 | + $pSheet | ||
| 659 | + ); | ||
| 660 | + return $newIndex; | ||
| 661 | + } | ||
| 662 | + | ||
| 663 | + /** | ||
| 664 | + * Get sheet count | ||
| 665 | + * | ||
| 666 | + * @return int | ||
| 667 | + */ | ||
| 668 | + public function getSheetCount() | ||
| 669 | + { | ||
| 670 | + return count($this->workSheetCollection); | ||
| 671 | + } | ||
| 672 | + | ||
| 673 | + /** | ||
| 674 | + * Get active sheet index | ||
| 675 | + * | ||
| 676 | + * @return int Active sheet index | ||
| 677 | + */ | ||
| 678 | + public function getActiveSheetIndex() | ||
| 679 | + { | ||
| 680 | + return $this->activeSheetIndex; | ||
| 681 | + } | ||
| 682 | + | ||
| 683 | + /** | ||
| 684 | + * Set active sheet index | ||
| 685 | + * | ||
| 686 | + * @param int $pIndex Active sheet index | ||
| 687 | + * @throws PHPExcel_Exception | ||
| 688 | + * @return PHPExcel_Worksheet | ||
| 689 | + */ | ||
| 690 | + public function setActiveSheetIndex($pIndex = 0) | ||
| 691 | + { | ||
| 692 | + $numSheets = count($this->workSheetCollection); | ||
| 693 | + | ||
| 694 | + if ($pIndex > $numSheets - 1) { | ||
| 695 | + throw new PHPExcel_Exception( | ||
| 696 | + "You tried to set a sheet active by the out of bounds index: {$pIndex}. The actual number of sheets is {$numSheets}." | ||
| 697 | + ); | ||
| 698 | + } else { | ||
| 699 | + $this->activeSheetIndex = $pIndex; | ||
| 700 | + } | ||
| 701 | + return $this->getActiveSheet(); | ||
| 702 | + } | ||
| 703 | + | ||
| 704 | + /** | ||
| 705 | + * Set active sheet index by name | ||
| 706 | + * | ||
| 707 | + * @param string $pValue Sheet title | ||
| 708 | + * @return PHPExcel_Worksheet | ||
| 709 | + * @throws PHPExcel_Exception | ||
| 710 | + */ | ||
| 711 | + public function setActiveSheetIndexByName($pValue = '') | ||
| 712 | + { | ||
| 713 | + if (($worksheet = $this->getSheetByName($pValue)) instanceof PHPExcel_Worksheet) { | ||
| 714 | + $this->setActiveSheetIndex($this->getIndex($worksheet)); | ||
| 715 | + return $worksheet; | ||
| 716 | + } | ||
| 717 | + | ||
| 718 | + throw new PHPExcel_Exception('Workbook does not contain sheet:' . $pValue); | ||
| 719 | + } | ||
| 720 | + | ||
| 721 | + /** | ||
| 722 | + * Get sheet names | ||
| 723 | + * | ||
| 724 | + * @return string[] | ||
| 725 | + */ | ||
| 726 | + public function getSheetNames() | ||
| 727 | + { | ||
| 728 | + $returnValue = array(); | ||
| 729 | + $worksheetCount = $this->getSheetCount(); | ||
| 730 | + for ($i = 0; $i < $worksheetCount; ++$i) { | ||
| 731 | + $returnValue[] = $this->getSheet($i)->getTitle(); | ||
| 732 | + } | ||
| 733 | + | ||
| 734 | + return $returnValue; | ||
| 735 | + } | ||
| 736 | + | ||
| 737 | + /** | ||
| 738 | + * Add external sheet | ||
| 739 | + * | ||
| 740 | + * @param PHPExcel_Worksheet $pSheet External sheet to add | ||
| 741 | + * @param int|null $iSheetIndex Index where sheet should go (0,1,..., or null for last) | ||
| 742 | + * @throws PHPExcel_Exception | ||
| 743 | + * @return PHPExcel_Worksheet | ||
| 744 | + */ | ||
| 745 | + public function addExternalSheet(PHPExcel_Worksheet $pSheet, $iSheetIndex = null) | ||
| 746 | + { | ||
| 747 | + if ($this->sheetNameExists($pSheet->getTitle())) { | ||
| 748 | + throw new PHPExcel_Exception("Workbook already contains a worksheet named '{$pSheet->getTitle()}'. Rename the external sheet first."); | ||
| 749 | + } | ||
| 750 | + | ||
| 751 | + // count how many cellXfs there are in this workbook currently, we will need this below | ||
| 752 | + $countCellXfs = count($this->cellXfCollection); | ||
| 753 | + | ||
| 754 | + // copy all the shared cellXfs from the external workbook and append them to the current | ||
| 755 | + foreach ($pSheet->getParent()->getCellXfCollection() as $cellXf) { | ||
| 756 | + $this->addCellXf(clone $cellXf); | ||
| 757 | + } | ||
| 758 | + | ||
| 759 | + // move sheet to this workbook | ||
| 760 | + $pSheet->rebindParent($this); | ||
| 761 | + | ||
| 762 | + // update the cellXfs | ||
| 763 | + foreach ($pSheet->getCellCollection(false) as $cellID) { | ||
| 764 | + $cell = $pSheet->getCell($cellID); | ||
| 765 | + $cell->setXfIndex($cell->getXfIndex() + $countCellXfs); | ||
| 766 | + } | ||
| 767 | + | ||
| 768 | + return $this->addSheet($pSheet, $iSheetIndex); | ||
| 769 | + } | ||
| 770 | + | ||
| 771 | + /** | ||
| 772 | + * Get named ranges | ||
| 773 | + * | ||
| 774 | + * @return PHPExcel_NamedRange[] | ||
| 775 | + */ | ||
| 776 | + public function getNamedRanges() | ||
| 777 | + { | ||
| 778 | + return $this->namedRanges; | ||
| 779 | + } | ||
| 780 | + | ||
| 781 | + /** | ||
| 782 | + * Add named range | ||
| 783 | + * | ||
| 784 | + * @param PHPExcel_NamedRange $namedRange | ||
| 785 | + * @return boolean | ||
| 786 | + */ | ||
| 787 | + public function addNamedRange(PHPExcel_NamedRange $namedRange) | ||
| 788 | + { | ||
| 789 | + if ($namedRange->getScope() == null) { | ||
| 790 | + // global scope | ||
| 791 | + $this->namedRanges[$namedRange->getName()] = $namedRange; | ||
| 792 | + } else { | ||
| 793 | + // local scope | ||
| 794 | + $this->namedRanges[$namedRange->getScope()->getTitle().'!'.$namedRange->getName()] = $namedRange; | ||
| 795 | + } | ||
| 796 | + return true; | ||
| 797 | + } | ||
| 798 | + | ||
| 799 | + /** | ||
| 800 | + * Get named range | ||
| 801 | + * | ||
| 802 | + * @param string $namedRange | ||
| 803 | + * @param PHPExcel_Worksheet|null $pSheet Scope. Use null for global scope | ||
| 804 | + * @return PHPExcel_NamedRange|null | ||
| 805 | + */ | ||
| 806 | + public function getNamedRange($namedRange, PHPExcel_Worksheet $pSheet = null) | ||
| 807 | + { | ||
| 808 | + $returnValue = null; | ||
| 809 | + | ||
| 810 | + if ($namedRange != '' && ($namedRange !== null)) { | ||
| 811 | + // first look for global defined name | ||
| 812 | + if (isset($this->namedRanges[$namedRange])) { | ||
| 813 | + $returnValue = $this->namedRanges[$namedRange]; | ||
| 814 | + } | ||
| 815 | + | ||
| 816 | + // then look for local defined name (has priority over global defined name if both names exist) | ||
| 817 | + if (($pSheet !== null) && isset($this->namedRanges[$pSheet->getTitle() . '!' . $namedRange])) { | ||
| 818 | + $returnValue = $this->namedRanges[$pSheet->getTitle() . '!' . $namedRange]; | ||
| 819 | + } | ||
| 820 | + } | ||
| 821 | + | ||
| 822 | + return $returnValue; | ||
| 823 | + } | ||
| 824 | + | ||
| 825 | + /** | ||
| 826 | + * Remove named range | ||
| 827 | + * | ||
| 828 | + * @param string $namedRange | ||
| 829 | + * @param PHPExcel_Worksheet|null $pSheet Scope: use null for global scope. | ||
| 830 | + * @return PHPExcel | ||
| 831 | + */ | ||
| 832 | + public function removeNamedRange($namedRange, PHPExcel_Worksheet $pSheet = null) | ||
| 833 | + { | ||
| 834 | + if ($pSheet === null) { | ||
| 835 | + if (isset($this->namedRanges[$namedRange])) { | ||
| 836 | + unset($this->namedRanges[$namedRange]); | ||
| 837 | + } | ||
| 838 | + } else { | ||
| 839 | + if (isset($this->namedRanges[$pSheet->getTitle() . '!' . $namedRange])) { | ||
| 840 | + unset($this->namedRanges[$pSheet->getTitle() . '!' . $namedRange]); | ||
| 841 | + } | ||
| 842 | + } | ||
| 843 | + return $this; | ||
| 844 | + } | ||
| 845 | + | ||
| 846 | + /** | ||
| 847 | + * Get worksheet iterator | ||
| 848 | + * | ||
| 849 | + * @return PHPExcel_WorksheetIterator | ||
| 850 | + */ | ||
| 851 | + public function getWorksheetIterator() | ||
| 852 | + { | ||
| 853 | + return new PHPExcel_WorksheetIterator($this); | ||
| 854 | + } | ||
| 855 | + | ||
| 856 | + /** | ||
| 857 | + * Copy workbook (!= clone!) | ||
| 858 | + * | ||
| 859 | + * @return PHPExcel | ||
| 860 | + */ | ||
| 861 | + public function copy() | ||
| 862 | + { | ||
| 863 | + $copied = clone $this; | ||
| 864 | + | ||
| 865 | + $worksheetCount = count($this->workSheetCollection); | ||
| 866 | + for ($i = 0; $i < $worksheetCount; ++$i) { | ||
| 867 | + $this->workSheetCollection[$i] = $this->workSheetCollection[$i]->copy(); | ||
| 868 | + $this->workSheetCollection[$i]->rebindParent($this); | ||
| 869 | + } | ||
| 870 | + | ||
| 871 | + return $copied; | ||
| 872 | + } | ||
| 873 | + | ||
| 874 | + /** | ||
| 875 | + * Implement PHP __clone to create a deep clone, not just a shallow copy. | ||
| 876 | + */ | ||
| 877 | + public function __clone() | ||
| 878 | + { | ||
| 879 | + foreach ($this as $key => $val) { | ||
| 880 | + if (is_object($val) || (is_array($val))) { | ||
| 881 | + $this->{$key} = unserialize(serialize($val)); | ||
| 882 | + } | ||
| 883 | + } | ||
| 884 | + } | ||
| 885 | + | ||
| 886 | + /** | ||
| 887 | + * Get the workbook collection of cellXfs | ||
| 888 | + * | ||
| 889 | + * @return PHPExcel_Style[] | ||
| 890 | + */ | ||
| 891 | + public function getCellXfCollection() | ||
| 892 | + { | ||
| 893 | + return $this->cellXfCollection; | ||
| 894 | + } | ||
| 895 | + | ||
| 896 | + /** | ||
| 897 | + * Get cellXf by index | ||
| 898 | + * | ||
| 899 | + * @param int $pIndex | ||
| 900 | + * @return PHPExcel_Style | ||
| 901 | + */ | ||
| 902 | + public function getCellXfByIndex($pIndex = 0) | ||
| 903 | + { | ||
| 904 | + return $this->cellXfCollection[$pIndex]; | ||
| 905 | + } | ||
| 906 | + | ||
| 907 | + /** | ||
| 908 | + * Get cellXf by hash code | ||
| 909 | + * | ||
| 910 | + * @param string $pValue | ||
| 911 | + * @return PHPExcel_Style|boolean False if no match found | ||
| 912 | + */ | ||
| 913 | + public function getCellXfByHashCode($pValue = '') | ||
| 914 | + { | ||
| 915 | + foreach ($this->cellXfCollection as $cellXf) { | ||
| 916 | + if ($cellXf->getHashCode() == $pValue) { | ||
| 917 | + return $cellXf; | ||
| 918 | + } | ||
| 919 | + } | ||
| 920 | + return false; | ||
| 921 | + } | ||
| 922 | + | ||
| 923 | + /** | ||
| 924 | + * Check if style exists in style collection | ||
| 925 | + * | ||
| 926 | + * @param PHPExcel_Style $pCellStyle | ||
| 927 | + * @return boolean | ||
| 928 | + */ | ||
| 929 | + public function cellXfExists($pCellStyle = null) | ||
| 930 | + { | ||
| 931 | + return in_array($pCellStyle, $this->cellXfCollection, true); | ||
| 932 | + } | ||
| 933 | + | ||
| 934 | + /** | ||
| 935 | + * Get default style | ||
| 936 | + * | ||
| 937 | + * @return PHPExcel_Style | ||
| 938 | + * @throws PHPExcel_Exception | ||
| 939 | + */ | ||
| 940 | + public function getDefaultStyle() | ||
| 941 | + { | ||
| 942 | + if (isset($this->cellXfCollection[0])) { | ||
| 943 | + return $this->cellXfCollection[0]; | ||
| 944 | + } | ||
| 945 | + throw new PHPExcel_Exception('No default style found for this workbook'); | ||
| 946 | + } | ||
| 947 | + | ||
| 948 | + /** | ||
| 949 | + * Add a cellXf to the workbook | ||
| 950 | + * | ||
| 951 | + * @param PHPExcel_Style $style | ||
| 952 | + */ | ||
| 953 | + public function addCellXf(PHPExcel_Style $style) | ||
| 954 | + { | ||
| 955 | + $this->cellXfCollection[] = $style; | ||
| 956 | + $style->setIndex(count($this->cellXfCollection) - 1); | ||
| 957 | + } | ||
| 958 | + | ||
| 959 | + /** | ||
| 960 | + * Remove cellXf by index. It is ensured that all cells get their xf index updated. | ||
| 961 | + * | ||
| 962 | + * @param integer $pIndex Index to cellXf | ||
| 963 | + * @throws PHPExcel_Exception | ||
| 964 | + */ | ||
| 965 | + public function removeCellXfByIndex($pIndex = 0) | ||
| 966 | + { | ||
| 967 | + if ($pIndex > count($this->cellXfCollection) - 1) { | ||
| 968 | + throw new PHPExcel_Exception("CellXf index is out of bounds."); | ||
| 969 | + } else { | ||
| 970 | + // first remove the cellXf | ||
| 971 | + array_splice($this->cellXfCollection, $pIndex, 1); | ||
| 972 | + | ||
| 973 | + // then update cellXf indexes for cells | ||
| 974 | + foreach ($this->workSheetCollection as $worksheet) { | ||
| 975 | + foreach ($worksheet->getCellCollection(false) as $cellID) { | ||
| 976 | + $cell = $worksheet->getCell($cellID); | ||
| 977 | + $xfIndex = $cell->getXfIndex(); | ||
| 978 | + if ($xfIndex > $pIndex) { | ||
| 979 | + // decrease xf index by 1 | ||
| 980 | + $cell->setXfIndex($xfIndex - 1); | ||
| 981 | + } elseif ($xfIndex == $pIndex) { | ||
| 982 | + // set to default xf index 0 | ||
| 983 | + $cell->setXfIndex(0); | ||
| 984 | + } | ||
| 985 | + } | ||
| 986 | + } | ||
| 987 | + } | ||
| 988 | + } | ||
| 989 | + | ||
| 990 | + /** | ||
| 991 | + * Get the cellXf supervisor | ||
| 992 | + * | ||
| 993 | + * @return PHPExcel_Style | ||
| 994 | + */ | ||
| 995 | + public function getCellXfSupervisor() | ||
| 996 | + { | ||
| 997 | + return $this->cellXfSupervisor; | ||
| 998 | + } | ||
| 999 | + | ||
| 1000 | + /** | ||
| 1001 | + * Get the workbook collection of cellStyleXfs | ||
| 1002 | + * | ||
| 1003 | + * @return PHPExcel_Style[] | ||
| 1004 | + */ | ||
| 1005 | + public function getCellStyleXfCollection() | ||
| 1006 | + { | ||
| 1007 | + return $this->cellStyleXfCollection; | ||
| 1008 | + } | ||
| 1009 | + | ||
| 1010 | + /** | ||
| 1011 | + * Get cellStyleXf by index | ||
| 1012 | + * | ||
| 1013 | + * @param integer $pIndex Index to cellXf | ||
| 1014 | + * @return PHPExcel_Style | ||
| 1015 | + */ | ||
| 1016 | + public function getCellStyleXfByIndex($pIndex = 0) | ||
| 1017 | + { | ||
| 1018 | + return $this->cellStyleXfCollection[$pIndex]; | ||
| 1019 | + } | ||
| 1020 | + | ||
| 1021 | + /** | ||
| 1022 | + * Get cellStyleXf by hash code | ||
| 1023 | + * | ||
| 1024 | + * @param string $pValue | ||
| 1025 | + * @return PHPExcel_Style|boolean False if no match found | ||
| 1026 | + */ | ||
| 1027 | + public function getCellStyleXfByHashCode($pValue = '') | ||
| 1028 | + { | ||
| 1029 | + foreach ($this->cellStyleXfCollection as $cellStyleXf) { | ||
| 1030 | + if ($cellStyleXf->getHashCode() == $pValue) { | ||
| 1031 | + return $cellStyleXf; | ||
| 1032 | + } | ||
| 1033 | + } | ||
| 1034 | + return false; | ||
| 1035 | + } | ||
| 1036 | + | ||
| 1037 | + /** | ||
| 1038 | + * Add a cellStyleXf to the workbook | ||
| 1039 | + * | ||
| 1040 | + * @param PHPExcel_Style $pStyle | ||
| 1041 | + */ | ||
| 1042 | + public function addCellStyleXf(PHPExcel_Style $pStyle) | ||
| 1043 | + { | ||
| 1044 | + $this->cellStyleXfCollection[] = $pStyle; | ||
| 1045 | + $pStyle->setIndex(count($this->cellStyleXfCollection) - 1); | ||
| 1046 | + } | ||
| 1047 | + | ||
| 1048 | + /** | ||
| 1049 | + * Remove cellStyleXf by index | ||
| 1050 | + * | ||
| 1051 | + * @param integer $pIndex Index to cellXf | ||
| 1052 | + * @throws PHPExcel_Exception | ||
| 1053 | + */ | ||
| 1054 | + public function removeCellStyleXfByIndex($pIndex = 0) | ||
| 1055 | + { | ||
| 1056 | + if ($pIndex > count($this->cellStyleXfCollection) - 1) { | ||
| 1057 | + throw new PHPExcel_Exception("CellStyleXf index is out of bounds."); | ||
| 1058 | + } else { | ||
| 1059 | + array_splice($this->cellStyleXfCollection, $pIndex, 1); | ||
| 1060 | + } | ||
| 1061 | + } | ||
| 1062 | + | ||
| 1063 | + /** | ||
| 1064 | + * Eliminate all unneeded cellXf and afterwards update the xfIndex for all cells | ||
| 1065 | + * and columns in the workbook | ||
| 1066 | + */ | ||
| 1067 | + public function garbageCollect() | ||
| 1068 | + { | ||
| 1069 | + // how many references are there to each cellXf ? | ||
| 1070 | + $countReferencesCellXf = array(); | ||
| 1071 | + foreach ($this->cellXfCollection as $index => $cellXf) { | ||
| 1072 | + $countReferencesCellXf[$index] = 0; | ||
| 1073 | + } | ||
| 1074 | + | ||
| 1075 | + foreach ($this->getWorksheetIterator() as $sheet) { | ||
| 1076 | + // from cells | ||
| 1077 | + foreach ($sheet->getCellCollection(false) as $cellID) { | ||
| 1078 | + $cell = $sheet->getCell($cellID); | ||
| 1079 | + ++$countReferencesCellXf[$cell->getXfIndex()]; | ||
| 1080 | + } | ||
| 1081 | + | ||
| 1082 | + // from row dimensions | ||
| 1083 | + foreach ($sheet->getRowDimensions() as $rowDimension) { | ||
| 1084 | + if ($rowDimension->getXfIndex() !== null) { | ||
| 1085 | + ++$countReferencesCellXf[$rowDimension->getXfIndex()]; | ||
| 1086 | + } | ||
| 1087 | + } | ||
| 1088 | + | ||
| 1089 | + // from column dimensions | ||
| 1090 | + foreach ($sheet->getColumnDimensions() as $columnDimension) { | ||
| 1091 | + ++$countReferencesCellXf[$columnDimension->getXfIndex()]; | ||
| 1092 | + } | ||
| 1093 | + } | ||
| 1094 | + | ||
| 1095 | + // remove cellXfs without references and create mapping so we can update xfIndex | ||
| 1096 | + // for all cells and columns | ||
| 1097 | + $countNeededCellXfs = 0; | ||
| 1098 | + $map = array(); | ||
| 1099 | + foreach ($this->cellXfCollection as $index => $cellXf) { | ||
| 1100 | + if ($countReferencesCellXf[$index] > 0 || $index == 0) { // we must never remove the first cellXf | ||
| 1101 | + ++$countNeededCellXfs; | ||
| 1102 | + } else { | ||
| 1103 | + unset($this->cellXfCollection[$index]); | ||
| 1104 | + } | ||
| 1105 | + $map[$index] = $countNeededCellXfs - 1; | ||
| 1106 | + } | ||
| 1107 | + $this->cellXfCollection = array_values($this->cellXfCollection); | ||
| 1108 | + | ||
| 1109 | + // update the index for all cellXfs | ||
| 1110 | + foreach ($this->cellXfCollection as $i => $cellXf) { | ||
| 1111 | + $cellXf->setIndex($i); | ||
| 1112 | + } | ||
| 1113 | + | ||
| 1114 | + // make sure there is always at least one cellXf (there should be) | ||
| 1115 | + if (empty($this->cellXfCollection)) { | ||
| 1116 | + $this->cellXfCollection[] = new PHPExcel_Style(); | ||
| 1117 | + } | ||
| 1118 | + | ||
| 1119 | + // update the xfIndex for all cells, row dimensions, column dimensions | ||
| 1120 | + foreach ($this->getWorksheetIterator() as $sheet) { | ||
| 1121 | + // for all cells | ||
| 1122 | + foreach ($sheet->getCellCollection(false) as $cellID) { | ||
| 1123 | + $cell = $sheet->getCell($cellID); | ||
| 1124 | + $cell->setXfIndex($map[$cell->getXfIndex()]); | ||
| 1125 | + } | ||
| 1126 | + | ||
| 1127 | + // for all row dimensions | ||
| 1128 | + foreach ($sheet->getRowDimensions() as $rowDimension) { | ||
| 1129 | + if ($rowDimension->getXfIndex() !== null) { | ||
| 1130 | + $rowDimension->setXfIndex($map[$rowDimension->getXfIndex()]); | ||
| 1131 | + } | ||
| 1132 | + } | ||
| 1133 | + | ||
| 1134 | + // for all column dimensions | ||
| 1135 | + foreach ($sheet->getColumnDimensions() as $columnDimension) { | ||
| 1136 | + $columnDimension->setXfIndex($map[$columnDimension->getXfIndex()]); | ||
| 1137 | + } | ||
| 1138 | + | ||
| 1139 | + // also do garbage collection for all the sheets | ||
| 1140 | + $sheet->garbageCollect(); | ||
| 1141 | + } | ||
| 1142 | + } | ||
| 1143 | + | ||
| 1144 | + /** | ||
| 1145 | + * Return the unique ID value assigned to this spreadsheet workbook | ||
| 1146 | + * | ||
| 1147 | + * @return string | ||
| 1148 | + */ | ||
| 1149 | + public function getID() | ||
| 1150 | + { | ||
| 1151 | + return $this->uniqueID; | ||
| 1152 | + } | ||
| 1153 | +} |
vendor/Classes/PHPExcel/Autoloader.php
0 → 100644
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +PHPExcel_Autoloader::register(); | ||
| 4 | +// As we always try to run the autoloader before anything else, we can use it to do a few | ||
| 5 | +// simple checks and initialisations | ||
| 6 | +//PHPExcel_Shared_ZipStreamWrapper::register(); | ||
| 7 | +// check mbstring.func_overload | ||
| 8 | +if (ini_get('mbstring.func_overload') & 2) { | ||
| 9 | + throw new PHPExcel_Exception('Multibyte function overloading in PHP must be disabled for string functions (2).'); | ||
| 10 | +} | ||
| 11 | +PHPExcel_Shared_String::buildCharacterSets(); | ||
| 12 | + | ||
| 13 | +/** | ||
| 14 | + * PHPExcel | ||
| 15 | + * | ||
| 16 | + * Copyright (c) 2006 - 2015 PHPExcel | ||
| 17 | + * | ||
| 18 | + * This library is free software; you can redistribute it and/or | ||
| 19 | + * modify it under the terms of the GNU Lesser General Public | ||
| 20 | + * License as published by the Free Software Foundation; either | ||
| 21 | + * version 2.1 of the License, or (at your option) any later version. | ||
| 22 | + * | ||
| 23 | + * This library is distributed in the hope that it will be useful, | ||
| 24 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 25 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 26 | + * Lesser General Public License for more details. | ||
| 27 | + * | ||
| 28 | + * You should have received a copy of the GNU Lesser General Public | ||
| 29 | + * License along with this library; if not, write to the Free Software | ||
| 30 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 31 | + * | ||
| 32 | + * @category PHPExcel | ||
| 33 | + * @package PHPExcel | ||
| 34 | + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) | ||
| 35 | + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL | ||
| 36 | + * @version ##VERSION##, ##DATE## | ||
| 37 | + */ | ||
| 38 | +class PHPExcel_Autoloader | ||
| 39 | +{ | ||
| 40 | + /** | ||
| 41 | + * Register the Autoloader with SPL | ||
| 42 | + * | ||
| 43 | + */ | ||
| 44 | + public static function register() | ||
| 45 | + { | ||
| 46 | + if (function_exists('__autoload')) { | ||
| 47 | + // Register any existing autoloader function with SPL, so we don't get any clashes | ||
| 48 | + spl_autoload_register('__autoload'); | ||
| 49 | + } | ||
| 50 | + // Register ourselves with SPL | ||
| 51 | + if (version_compare(PHP_VERSION, '5.3.0') >= 0) { | ||
| 52 | + return spl_autoload_register(array('PHPExcel_Autoloader', 'load'), true, true); | ||
| 53 | + } else { | ||
| 54 | + return spl_autoload_register(array('PHPExcel_Autoloader', 'load')); | ||
| 55 | + } | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | + /** | ||
| 59 | + * Autoload a class identified by name | ||
| 60 | + * | ||
| 61 | + * @param string $pClassName Name of the object to load | ||
| 62 | + */ | ||
| 63 | + public static function load($pClassName) | ||
| 64 | + { | ||
| 65 | + if ((class_exists($pClassName, false)) || (strpos($pClassName, 'PHPExcel') !== 0)) { | ||
| 66 | + // Either already loaded, or not a PHPExcel class request | ||
| 67 | + return false; | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + $pClassFilePath = PHPEXCEL_ROOT . | ||
| 71 | + str_replace('_', DIRECTORY_SEPARATOR, $pClassName) . | ||
| 72 | + '.php'; | ||
| 73 | + | ||
| 74 | + if ((file_exists($pClassFilePath) === false) || (is_readable($pClassFilePath) === false)) { | ||
| 75 | + // Can't load | ||
| 76 | + return false; | ||
| 77 | + } | ||
| 78 | + | ||
| 79 | + require($pClassFilePath); | ||
| 80 | + } | ||
| 81 | +} |
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +/** | ||
| 4 | + * PHPExcel_CachedObjectStorage_APC | ||
| 5 | + * | ||
| 6 | + * Copyright (c) 2006 - 2015 PHPExcel | ||
| 7 | + * | ||
| 8 | + * This library is free software; you can redistribute it and/or | ||
| 9 | + * modify it under the terms of the GNU Lesser General Public | ||
| 10 | + * License as published by the Free Software Foundation; either | ||
| 11 | + * version 2.1 of the License, or (at your option) any later version. | ||
| 12 | + * | ||
| 13 | + * This library is distributed in the hope that it will be useful, | ||
| 14 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 16 | + * Lesser General Public License for more details. | ||
| 17 | + * | ||
| 18 | + * You should have received a copy of the GNU Lesser General Public | ||
| 19 | + * License along with this library; if not, write to the Free Software | ||
| 20 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 21 | + * | ||
| 22 | + * @category PHPExcel | ||
| 23 | + * @package PHPExcel_CachedObjectStorage | ||
| 24 | + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) | ||
| 25 | + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL | ||
| 26 | + * @version ##VERSION##, ##DATE## | ||
| 27 | + */ | ||
| 28 | +class PHPExcel_CachedObjectStorage_APC extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache | ||
| 29 | +{ | ||
| 30 | + /** | ||
| 31 | + * Prefix used to uniquely identify cache data for this worksheet | ||
| 32 | + * | ||
| 33 | + * @access private | ||
| 34 | + * @var string | ||
| 35 | + */ | ||
| 36 | + private $cachePrefix = null; | ||
| 37 | + | ||
| 38 | + /** | ||
| 39 | + * Cache timeout | ||
| 40 | + * | ||
| 41 | + * @access private | ||
| 42 | + * @var integer | ||
| 43 | + */ | ||
| 44 | + private $cacheTime = 600; | ||
| 45 | + | ||
| 46 | + /** | ||
| 47 | + * Store cell data in cache for the current cell object if it's "dirty", | ||
| 48 | + * and the 'nullify' the current cell object | ||
| 49 | + * | ||
| 50 | + * @access private | ||
| 51 | + * @return void | ||
| 52 | + * @throws PHPExcel_Exception | ||
| 53 | + */ | ||
| 54 | + protected function storeData() | ||
| 55 | + { | ||
| 56 | + if ($this->currentCellIsDirty && !empty($this->currentObjectID)) { | ||
| 57 | + $this->currentObject->detach(); | ||
| 58 | + | ||
| 59 | + if (!apc_store( | ||
| 60 | + $this->cachePrefix . $this->currentObjectID . '.cache', | ||
| 61 | + serialize($this->currentObject), | ||
| 62 | + $this->cacheTime | ||
| 63 | + )) { | ||
| 64 | + $this->__destruct(); | ||
| 65 | + throw new PHPExcel_Exception('Failed to store cell ' . $this->currentObjectID . ' in APC'); | ||
| 66 | + } | ||
| 67 | + $this->currentCellIsDirty = false; | ||
| 68 | + } | ||
| 69 | + $this->currentObjectID = $this->currentObject = null; | ||
| 70 | + } | ||
| 71 | + | ||
| 72 | + /** | ||
| 73 | + * Add or Update a cell in cache identified by coordinate address | ||
| 74 | + * | ||
| 75 | + * @access public | ||
| 76 | + * @param string $pCoord Coordinate address of the cell to update | ||
| 77 | + * @param PHPExcel_Cell $cell Cell to update | ||
| 78 | + * @return PHPExcel_Cell | ||
| 79 | + * @throws PHPExcel_Exception | ||
| 80 | + */ | ||
| 81 | + public function addCacheData($pCoord, PHPExcel_Cell $cell) | ||
| 82 | + { | ||
| 83 | + if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) { | ||
| 84 | + $this->storeData(); | ||
| 85 | + } | ||
| 86 | + $this->cellCache[$pCoord] = true; | ||
| 87 | + | ||
| 88 | + $this->currentObjectID = $pCoord; | ||
| 89 | + $this->currentObject = $cell; | ||
| 90 | + $this->currentCellIsDirty = true; | ||
| 91 | + | ||
| 92 | + return $cell; | ||
| 93 | + } | ||
| 94 | + | ||
| 95 | + /** | ||
| 96 | + * Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell? | ||
| 97 | + * | ||
| 98 | + * @access public | ||
| 99 | + * @param string $pCoord Coordinate address of the cell to check | ||
| 100 | + * @throws PHPExcel_Exception | ||
| 101 | + * @return boolean | ||
| 102 | + */ | ||
| 103 | + public function isDataSet($pCoord) | ||
| 104 | + { | ||
| 105 | + // Check if the requested entry is the current object, or exists in the cache | ||
| 106 | + if (parent::isDataSet($pCoord)) { | ||
| 107 | + if ($this->currentObjectID == $pCoord) { | ||
| 108 | + return true; | ||
| 109 | + } | ||
| 110 | + // Check if the requested entry still exists in apc | ||
| 111 | + $success = apc_fetch($this->cachePrefix.$pCoord.'.cache'); | ||
| 112 | + if ($success === false) { | ||
| 113 | + // Entry no longer exists in APC, so clear it from the cache array | ||
| 114 | + parent::deleteCacheData($pCoord); | ||
| 115 | + throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in APC cache'); | ||
| 116 | + } | ||
| 117 | + return true; | ||
| 118 | + } | ||
| 119 | + return false; | ||
| 120 | + } | ||
| 121 | + | ||
| 122 | + /** | ||
| 123 | + * Get cell at a specific coordinate | ||
| 124 | + * | ||
| 125 | + * @access public | ||
| 126 | + * @param string $pCoord Coordinate of the cell | ||
| 127 | + * @throws PHPExcel_Exception | ||
| 128 | + * @return PHPExcel_Cell Cell that was found, or null if not found | ||
| 129 | + */ | ||
| 130 | + public function getCacheData($pCoord) | ||
| 131 | + { | ||
| 132 | + if ($pCoord === $this->currentObjectID) { | ||
| 133 | + return $this->currentObject; | ||
| 134 | + } | ||
| 135 | + $this->storeData(); | ||
| 136 | + | ||
| 137 | + // Check if the entry that has been requested actually exists | ||
| 138 | + if (parent::isDataSet($pCoord)) { | ||
| 139 | + $obj = apc_fetch($this->cachePrefix . $pCoord . '.cache'); | ||
| 140 | + if ($obj === false) { | ||
| 141 | + // Entry no longer exists in APC, so clear it from the cache array | ||
| 142 | + parent::deleteCacheData($pCoord); | ||
| 143 | + throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in APC cache'); | ||
| 144 | + } | ||
| 145 | + } else { | ||
| 146 | + // Return null if requested entry doesn't exist in cache | ||
| 147 | + return null; | ||
| 148 | + } | ||
| 149 | + | ||
| 150 | + // Set current entry to the requested entry | ||
| 151 | + $this->currentObjectID = $pCoord; | ||
| 152 | + $this->currentObject = unserialize($obj); | ||
| 153 | + // Re-attach this as the cell's parent | ||
| 154 | + $this->currentObject->attach($this); | ||
| 155 | + | ||
| 156 | + // Return requested entry | ||
| 157 | + return $this->currentObject; | ||
| 158 | + } | ||
| 159 | + | ||
| 160 | + /** | ||
| 161 | + * Get a list of all cell addresses currently held in cache | ||
| 162 | + * | ||
| 163 | + * @return string[] | ||
| 164 | + */ | ||
| 165 | + public function getCellList() | ||
| 166 | + { | ||
| 167 | + if ($this->currentObjectID !== null) { | ||
| 168 | + $this->storeData(); | ||
| 169 | + } | ||
| 170 | + | ||
| 171 | + return parent::getCellList(); | ||
| 172 | + } | ||
| 173 | + | ||
| 174 | + /** | ||
| 175 | + * Delete a cell in cache identified by coordinate address | ||
| 176 | + * | ||
| 177 | + * @access public | ||
| 178 | + * @param string $pCoord Coordinate address of the cell to delete | ||
| 179 | + * @throws PHPExcel_Exception | ||
| 180 | + */ | ||
| 181 | + public function deleteCacheData($pCoord) | ||
| 182 | + { | ||
| 183 | + // Delete the entry from APC | ||
| 184 | + apc_delete($this->cachePrefix.$pCoord.'.cache'); | ||
| 185 | + | ||
| 186 | + // Delete the entry from our cell address array | ||
| 187 | + parent::deleteCacheData($pCoord); | ||
| 188 | + } | ||
| 189 | + | ||
| 190 | + /** | ||
| 191 | + * Clone the cell collection | ||
| 192 | + * | ||
| 193 | + * @access public | ||
| 194 | + * @param PHPExcel_Worksheet $parent The new worksheet | ||
| 195 | + * @throws PHPExcel_Exception | ||
| 196 | + * @return void | ||
| 197 | + */ | ||
| 198 | + public function copyCellCollection(PHPExcel_Worksheet $parent) | ||
| 199 | + { | ||
| 200 | + parent::copyCellCollection($parent); | ||
| 201 | + // Get a new id for the new file name | ||
| 202 | + $baseUnique = $this->getUniqueID(); | ||
| 203 | + $newCachePrefix = substr(md5($baseUnique), 0, 8) . '.'; | ||
| 204 | + $cacheList = $this->getCellList(); | ||
| 205 | + foreach ($cacheList as $cellID) { | ||
| 206 | + if ($cellID != $this->currentObjectID) { | ||
| 207 | + $obj = apc_fetch($this->cachePrefix . $cellID . '.cache'); | ||
| 208 | + if ($obj === false) { | ||
| 209 | + // Entry no longer exists in APC, so clear it from the cache array | ||
| 210 | + parent::deleteCacheData($cellID); | ||
| 211 | + throw new PHPExcel_Exception('Cell entry ' . $cellID . ' no longer exists in APC'); | ||
| 212 | + } | ||
| 213 | + if (!apc_store($newCachePrefix . $cellID . '.cache', $obj, $this->cacheTime)) { | ||
| 214 | + $this->__destruct(); | ||
| 215 | + throw new PHPExcel_Exception('Failed to store cell ' . $cellID . ' in APC'); | ||
| 216 | + } | ||
| 217 | + } | ||
| 218 | + } | ||
| 219 | + $this->cachePrefix = $newCachePrefix; | ||
| 220 | + } | ||
| 221 | + | ||
| 222 | + /** | ||
| 223 | + * Clear the cell collection and disconnect from our parent | ||
| 224 | + * | ||
| 225 | + * @return void | ||
| 226 | + */ | ||
| 227 | + public function unsetWorksheetCells() | ||
| 228 | + { | ||
| 229 | + if ($this->currentObject !== null) { | ||
| 230 | + $this->currentObject->detach(); | ||
| 231 | + $this->currentObject = $this->currentObjectID = null; | ||
| 232 | + } | ||
| 233 | + | ||
| 234 | + // Flush the APC cache | ||
| 235 | + $this->__destruct(); | ||
| 236 | + | ||
| 237 | + $this->cellCache = array(); | ||
| 238 | + | ||
| 239 | + // detach ourself from the worksheet, so that it can then delete this object successfully | ||
| 240 | + $this->parent = null; | ||
| 241 | + } | ||
| 242 | + | ||
| 243 | + /** | ||
| 244 | + * Initialise this new cell collection | ||
| 245 | + * | ||
| 246 | + * @param PHPExcel_Worksheet $parent The worksheet for this cell collection | ||
| 247 | + * @param array of mixed $arguments Additional initialisation arguments | ||
| 248 | + */ | ||
| 249 | + public function __construct(PHPExcel_Worksheet $parent, $arguments) | ||
| 250 | + { | ||
| 251 | + $cacheTime = (isset($arguments['cacheTime'])) ? $arguments['cacheTime'] : 600; | ||
| 252 | + | ||
| 253 | + if ($this->cachePrefix === null) { | ||
| 254 | + $baseUnique = $this->getUniqueID(); | ||
| 255 | + $this->cachePrefix = substr(md5($baseUnique), 0, 8) . '.'; | ||
| 256 | + $this->cacheTime = $cacheTime; | ||
| 257 | + | ||
| 258 | + parent::__construct($parent); | ||
| 259 | + } | ||
| 260 | + } | ||
| 261 | + | ||
| 262 | + /** | ||
| 263 | + * Destroy this cell collection | ||
| 264 | + */ | ||
| 265 | + public function __destruct() | ||
| 266 | + { | ||
| 267 | + $cacheList = $this->getCellList(); | ||
| 268 | + foreach ($cacheList as $cellID) { | ||
| 269 | + apc_delete($this->cachePrefix . $cellID . '.cache'); | ||
| 270 | + } | ||
| 271 | + } | ||
| 272 | + | ||
| 273 | + /** | ||
| 274 | + * Identify whether the caching method is currently available | ||
| 275 | + * Some methods are dependent on the availability of certain extensions being enabled in the PHP build | ||
| 276 | + * | ||
| 277 | + * @return boolean | ||
| 278 | + */ | ||
| 279 | + public static function cacheMethodIsAvailable() | ||
| 280 | + { | ||
| 281 | + if (!function_exists('apc_store')) { | ||
| 282 | + return false; | ||
| 283 | + } | ||
| 284 | + if (apc_sma_info() === false) { | ||
| 285 | + return false; | ||
| 286 | + } | ||
| 287 | + | ||
| 288 | + return true; | ||
| 289 | + } | ||
| 290 | +} |
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +/** | ||
| 4 | + * PHPExcel_CachedObjectStorage_CacheBase | ||
| 5 | + * | ||
| 6 | + * Copyright (c) 2006 - 2015 PHPExcel | ||
| 7 | + * | ||
| 8 | + * This library is free software; you can redistribute it and/or | ||
| 9 | + * modify it under the terms of the GNU Lesser General Public | ||
| 10 | + * License as published by the Free Software Foundation; either | ||
| 11 | + * version 2.1 of the License, or (at your option) any later version. | ||
| 12 | + * | ||
| 13 | + * This library is distributed in the hope that it will be useful, | ||
| 14 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 16 | + * Lesser General Public License for more details. | ||
| 17 | + * | ||
| 18 | + * You should have received a copy of the GNU Lesser General Public | ||
| 19 | + * License along with this library; if not, write to the Free Software | ||
| 20 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 21 | + * | ||
| 22 | + * @category PHPExcel | ||
| 23 | + * @package PHPExcel_CachedObjectStorage | ||
| 24 | + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) | ||
| 25 | + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL | ||
| 26 | + * @version ##VERSION##, ##DATE## | ||
| 27 | + */ | ||
| 28 | +abstract class PHPExcel_CachedObjectStorage_CacheBase | ||
| 29 | +{ | ||
| 30 | + /** | ||
| 31 | + * Parent worksheet | ||
| 32 | + * | ||
| 33 | + * @var PHPExcel_Worksheet | ||
| 34 | + */ | ||
| 35 | + protected $parent; | ||
| 36 | + | ||
| 37 | + /** | ||
| 38 | + * The currently active Cell | ||
| 39 | + * | ||
| 40 | + * @var PHPExcel_Cell | ||
| 41 | + */ | ||
| 42 | + protected $currentObject = null; | ||
| 43 | + | ||
| 44 | + /** | ||
| 45 | + * Coordinate address of the currently active Cell | ||
| 46 | + * | ||
| 47 | + * @var string | ||
| 48 | + */ | ||
| 49 | + protected $currentObjectID = null; | ||
| 50 | + | ||
| 51 | + /** | ||
| 52 | + * Flag indicating whether the currently active Cell requires saving | ||
| 53 | + * | ||
| 54 | + * @var boolean | ||
| 55 | + */ | ||
| 56 | + protected $currentCellIsDirty = true; | ||
| 57 | + | ||
| 58 | + /** | ||
| 59 | + * An array of cells or cell pointers for the worksheet cells held in this cache, | ||
| 60 | + * and indexed by their coordinate address within the worksheet | ||
| 61 | + * | ||
| 62 | + * @var array of mixed | ||
| 63 | + */ | ||
| 64 | + protected $cellCache = array(); | ||
| 65 | + | ||
| 66 | + /** | ||
| 67 | + * Initialise this new cell collection | ||
| 68 | + * | ||
| 69 | + * @param PHPExcel_Worksheet $parent The worksheet for this cell collection | ||
| 70 | + */ | ||
| 71 | + public function __construct(PHPExcel_Worksheet $parent) | ||
| 72 | + { | ||
| 73 | + // Set our parent worksheet. | ||
| 74 | + // This is maintained within the cache controller to facilitate re-attaching it to PHPExcel_Cell objects when | ||
| 75 | + // they are woken from a serialized state | ||
| 76 | + $this->parent = $parent; | ||
| 77 | + } | ||
| 78 | + | ||
| 79 | + /** | ||
| 80 | + * Return the parent worksheet for this cell collection | ||
| 81 | + * | ||
| 82 | + * @return PHPExcel_Worksheet | ||
| 83 | + */ | ||
| 84 | + public function getParent() | ||
| 85 | + { | ||
| 86 | + return $this->parent; | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + /** | ||
| 90 | + * Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell? | ||
| 91 | + * | ||
| 92 | + * @param string $pCoord Coordinate address of the cell to check | ||
| 93 | + * @return boolean | ||
| 94 | + */ | ||
| 95 | + public function isDataSet($pCoord) | ||
| 96 | + { | ||
| 97 | + if ($pCoord === $this->currentObjectID) { | ||
| 98 | + return true; | ||
| 99 | + } | ||
| 100 | + // Check if the requested entry exists in the cache | ||
| 101 | + return isset($this->cellCache[$pCoord]); | ||
| 102 | + } | ||
| 103 | + | ||
| 104 | + /** | ||
| 105 | + * Move a cell object from one address to another | ||
| 106 | + * | ||
| 107 | + * @param string $fromAddress Current address of the cell to move | ||
| 108 | + * @param string $toAddress Destination address of the cell to move | ||
| 109 | + * @return boolean | ||
| 110 | + */ | ||
| 111 | + public function moveCell($fromAddress, $toAddress) | ||
| 112 | + { | ||
| 113 | + if ($fromAddress === $this->currentObjectID) { | ||
| 114 | + $this->currentObjectID = $toAddress; | ||
| 115 | + } | ||
| 116 | + $this->currentCellIsDirty = true; | ||
| 117 | + if (isset($this->cellCache[$fromAddress])) { | ||
| 118 | + $this->cellCache[$toAddress] = &$this->cellCache[$fromAddress]; | ||
| 119 | + unset($this->cellCache[$fromAddress]); | ||
| 120 | + } | ||
| 121 | + | ||
| 122 | + return true; | ||
| 123 | + } | ||
| 124 | + | ||
| 125 | + /** | ||
| 126 | + * Add or Update a cell in cache | ||
| 127 | + * | ||
| 128 | + * @param PHPExcel_Cell $cell Cell to update | ||
| 129 | + * @return PHPExcel_Cell | ||
| 130 | + * @throws PHPExcel_Exception | ||
| 131 | + */ | ||
| 132 | + public function updateCacheData(PHPExcel_Cell $cell) | ||
| 133 | + { | ||
| 134 | + return $this->addCacheData($cell->getCoordinate(), $cell); | ||
| 135 | + } | ||
| 136 | + | ||
| 137 | + /** | ||
| 138 | + * Delete a cell in cache identified by coordinate address | ||
| 139 | + * | ||
| 140 | + * @param string $pCoord Coordinate address of the cell to delete | ||
| 141 | + * @throws PHPExcel_Exception | ||
| 142 | + */ | ||
| 143 | + public function deleteCacheData($pCoord) | ||
| 144 | + { | ||
| 145 | + if ($pCoord === $this->currentObjectID && !is_null($this->currentObject)) { | ||
| 146 | + $this->currentObject->detach(); | ||
| 147 | + $this->currentObjectID = $this->currentObject = null; | ||
| 148 | + } | ||
| 149 | + | ||
| 150 | + if (is_object($this->cellCache[$pCoord])) { | ||
| 151 | + $this->cellCache[$pCoord]->detach(); | ||
| 152 | + unset($this->cellCache[$pCoord]); | ||
| 153 | + } | ||
| 154 | + $this->currentCellIsDirty = false; | ||
| 155 | + } | ||
| 156 | + | ||
| 157 | + /** | ||
| 158 | + * Get a list of all cell addresses currently held in cache | ||
| 159 | + * | ||
| 160 | + * @return string[] | ||
| 161 | + */ | ||
| 162 | + public function getCellList() | ||
| 163 | + { | ||
| 164 | + return array_keys($this->cellCache); | ||
| 165 | + } | ||
| 166 | + | ||
| 167 | + /** | ||
| 168 | + * Sort the list of all cell addresses currently held in cache by row and column | ||
| 169 | + * | ||
| 170 | + * @return string[] | ||
| 171 | + */ | ||
| 172 | + public function getSortedCellList() | ||
| 173 | + { | ||
| 174 | + $sortKeys = array(); | ||
| 175 | + foreach ($this->getCellList() as $coord) { | ||
| 176 | + sscanf($coord, '%[A-Z]%d', $column, $row); | ||
| 177 | + $sortKeys[sprintf('%09d%3s', $row, $column)] = $coord; | ||
| 178 | + } | ||
| 179 | + ksort($sortKeys); | ||
| 180 | + | ||
| 181 | + return array_values($sortKeys); | ||
| 182 | + } | ||
| 183 | + | ||
| 184 | + /** | ||
| 185 | + * Get highest worksheet column and highest row that have cell records | ||
| 186 | + * | ||
| 187 | + * @return array Highest column name and highest row number | ||
| 188 | + */ | ||
| 189 | + public function getHighestRowAndColumn() | ||
| 190 | + { | ||
| 191 | + // Lookup highest column and highest row | ||
| 192 | + $col = array('A' => '1A'); | ||
| 193 | + $row = array(1); | ||
| 194 | + foreach ($this->getCellList() as $coord) { | ||
| 195 | + sscanf($coord, '%[A-Z]%d', $c, $r); | ||
| 196 | + $row[$r] = $r; | ||
| 197 | + $col[$c] = strlen($c).$c; | ||
| 198 | + } | ||
| 199 | + if (!empty($row)) { | ||
| 200 | + // Determine highest column and row | ||
| 201 | + $highestRow = max($row); | ||
| 202 | + $highestColumn = substr(max($col), 1); | ||
| 203 | + } | ||
| 204 | + | ||
| 205 | + return array( | ||
| 206 | + 'row' => $highestRow, | ||
| 207 | + 'column' => $highestColumn | ||
| 208 | + ); | ||
| 209 | + } | ||
| 210 | + | ||
| 211 | + /** | ||
| 212 | + * Return the cell address of the currently active cell object | ||
| 213 | + * | ||
| 214 | + * @return string | ||
| 215 | + */ | ||
| 216 | + public function getCurrentAddress() | ||
| 217 | + { | ||
| 218 | + return $this->currentObjectID; | ||
| 219 | + } | ||
| 220 | + | ||
| 221 | + /** | ||
| 222 | + * Return the column address of the currently active cell object | ||
| 223 | + * | ||
| 224 | + * @return string | ||
| 225 | + */ | ||
| 226 | + public function getCurrentColumn() | ||
| 227 | + { | ||
| 228 | + sscanf($this->currentObjectID, '%[A-Z]%d', $column, $row); | ||
| 229 | + return $column; | ||
| 230 | + } | ||
| 231 | + | ||
| 232 | + /** | ||
| 233 | + * Return the row address of the currently active cell object | ||
| 234 | + * | ||
| 235 | + * @return integer | ||
| 236 | + */ | ||
| 237 | + public function getCurrentRow() | ||
| 238 | + { | ||
| 239 | + sscanf($this->currentObjectID, '%[A-Z]%d', $column, $row); | ||
| 240 | + return (integer) $row; | ||
| 241 | + } | ||
| 242 | + | ||
| 243 | + /** | ||
| 244 | + * Get highest worksheet column | ||
| 245 | + * | ||
| 246 | + * @param string $row Return the highest column for the specified row, | ||
| 247 | + * or the highest column of any row if no row number is passed | ||
| 248 | + * @return string Highest column name | ||
| 249 | + */ | ||
| 250 | + public function getHighestColumn($row = null) | ||
| 251 | + { | ||
| 252 | + if ($row == null) { | ||
| 253 | + $colRow = $this->getHighestRowAndColumn(); | ||
| 254 | + return $colRow['column']; | ||
| 255 | + } | ||
| 256 | + | ||
| 257 | + $columnList = array(1); | ||
| 258 | + foreach ($this->getCellList() as $coord) { | ||
| 259 | + sscanf($coord, '%[A-Z]%d', $c, $r); | ||
| 260 | + if ($r != $row) { | ||
| 261 | + continue; | ||
| 262 | + } | ||
| 263 | + $columnList[] = PHPExcel_Cell::columnIndexFromString($c); | ||
| 264 | + } | ||
| 265 | + return PHPExcel_Cell::stringFromColumnIndex(max($columnList) - 1); | ||
| 266 | + } | ||
| 267 | + | ||
| 268 | + /** | ||
| 269 | + * Get highest worksheet row | ||
| 270 | + * | ||
| 271 | + * @param string $column Return the highest row for the specified column, | ||
| 272 | + * or the highest row of any column if no column letter is passed | ||
| 273 | + * @return int Highest row number | ||
| 274 | + */ | ||
| 275 | + public function getHighestRow($column = null) | ||
| 276 | + { | ||
| 277 | + if ($column == null) { | ||
| 278 | + $colRow = $this->getHighestRowAndColumn(); | ||
| 279 | + return $colRow['row']; | ||
| 280 | + } | ||
| 281 | + | ||
| 282 | + $rowList = array(0); | ||
| 283 | + foreach ($this->getCellList() as $coord) { | ||
| 284 | + sscanf($coord, '%[A-Z]%d', $c, $r); | ||
| 285 | + if ($c != $column) { | ||
| 286 | + continue; | ||
| 287 | + } | ||
| 288 | + $rowList[] = $r; | ||
| 289 | + } | ||
| 290 | + | ||
| 291 | + return max($rowList); | ||
| 292 | + } | ||
| 293 | + | ||
| 294 | + /** | ||
| 295 | + * Generate a unique ID for cache referencing | ||
| 296 | + * | ||
| 297 | + * @return string Unique Reference | ||
| 298 | + */ | ||
| 299 | + protected function getUniqueID() | ||
| 300 | + { | ||
| 301 | + if (function_exists('posix_getpid')) { | ||
| 302 | + $baseUnique = posix_getpid(); | ||
| 303 | + } else { | ||
| 304 | + $baseUnique = mt_rand(); | ||
| 305 | + } | ||
| 306 | + return uniqid($baseUnique, true); | ||
| 307 | + } | ||
| 308 | + | ||
| 309 | + /** | ||
| 310 | + * Clone the cell collection | ||
| 311 | + * | ||
| 312 | + * @param PHPExcel_Worksheet $parent The new worksheet | ||
| 313 | + * @return void | ||
| 314 | + */ | ||
| 315 | + public function copyCellCollection(PHPExcel_Worksheet $parent) | ||
| 316 | + { | ||
| 317 | + $this->currentCellIsDirty; | ||
| 318 | + $this->storeData(); | ||
| 319 | + | ||
| 320 | + $this->parent = $parent; | ||
| 321 | + if (($this->currentObject !== null) && (is_object($this->currentObject))) { | ||
| 322 | + $this->currentObject->attach($this); | ||
| 323 | + } | ||
| 324 | + } // function copyCellCollection() | ||
| 325 | + | ||
| 326 | + /** | ||
| 327 | + * Remove a row, deleting all cells in that row | ||
| 328 | + * | ||
| 329 | + * @param string $row Row number to remove | ||
| 330 | + * @return void | ||
| 331 | + */ | ||
| 332 | + public function removeRow($row) | ||
| 333 | + { | ||
| 334 | + foreach ($this->getCellList() as $coord) { | ||
| 335 | + sscanf($coord, '%[A-Z]%d', $c, $r); | ||
| 336 | + if ($r == $row) { | ||
| 337 | + $this->deleteCacheData($coord); | ||
| 338 | + } | ||
| 339 | + } | ||
| 340 | + } | ||
| 341 | + | ||
| 342 | + /** | ||
| 343 | + * Remove a column, deleting all cells in that column | ||
| 344 | + * | ||
| 345 | + * @param string $column Column ID to remove | ||
| 346 | + * @return void | ||
| 347 | + */ | ||
| 348 | + public function removeColumn($column) | ||
| 349 | + { | ||
| 350 | + foreach ($this->getCellList() as $coord) { | ||
| 351 | + sscanf($coord, '%[A-Z]%d', $c, $r); | ||
| 352 | + if ($c == $column) { | ||
| 353 | + $this->deleteCacheData($coord); | ||
| 354 | + } | ||
| 355 | + } | ||
| 356 | + } | ||
| 357 | + | ||
| 358 | + /** | ||
| 359 | + * Identify whether the caching method is currently available | ||
| 360 | + * Some methods are dependent on the availability of certain extensions being enabled in the PHP build | ||
| 361 | + * | ||
| 362 | + * @return boolean | ||
| 363 | + */ | ||
| 364 | + public static function cacheMethodIsAvailable() | ||
| 365 | + { | ||
| 366 | + return true; | ||
| 367 | + } | ||
| 368 | +} |
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +/** | ||
| 4 | + * PHPExcel_CachedObjectStorage_DiscISAM | ||
| 5 | + * | ||
| 6 | + * Copyright (c) 2006 - 2015 PHPExcel | ||
| 7 | + * | ||
| 8 | + * This library is free software; you can redistribute it and/or | ||
| 9 | + * modify it under the terms of the GNU Lesser General Public | ||
| 10 | + * License as published by the Free Software Foundation; either | ||
| 11 | + * version 2.1 of the License, or (at your option) any later version. | ||
| 12 | + * | ||
| 13 | + * This library is distributed in the hope that it will be useful, | ||
| 14 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 16 | + * Lesser General Public License for more details. | ||
| 17 | + * | ||
| 18 | + * You should have received a copy of the GNU Lesser General Public | ||
| 19 | + * License along with this library; if not, write to the Free Software | ||
| 20 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 21 | + * | ||
| 22 | + * @category PHPExcel | ||
| 23 | + * @package PHPExcel_CachedObjectStorage | ||
| 24 | + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) | ||
| 25 | + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL | ||
| 26 | + * @version ##VERSION##, ##DATE## | ||
| 27 | + */ | ||
| 28 | +class PHPExcel_CachedObjectStorage_DiscISAM extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache | ||
| 29 | +{ | ||
| 30 | + /** | ||
| 31 | + * Name of the file for this cache | ||
| 32 | + * | ||
| 33 | + * @var string | ||
| 34 | + */ | ||
| 35 | + private $fileName = null; | ||
| 36 | + | ||
| 37 | + /** | ||
| 38 | + * File handle for this cache file | ||
| 39 | + * | ||
| 40 | + * @var resource | ||
| 41 | + */ | ||
| 42 | + private $fileHandle = null; | ||
| 43 | + | ||
| 44 | + /** | ||
| 45 | + * Directory/Folder where the cache file is located | ||
| 46 | + * | ||
| 47 | + * @var string | ||
| 48 | + */ | ||
| 49 | + private $cacheDirectory = null; | ||
| 50 | + | ||
| 51 | + /** | ||
| 52 | + * Store cell data in cache for the current cell object if it's "dirty", | ||
| 53 | + * and the 'nullify' the current cell object | ||
| 54 | + * | ||
| 55 | + * @return void | ||
| 56 | + * @throws PHPExcel_Exception | ||
| 57 | + */ | ||
| 58 | + protected function storeData() | ||
| 59 | + { | ||
| 60 | + if ($this->currentCellIsDirty && !empty($this->currentObjectID)) { | ||
| 61 | + $this->currentObject->detach(); | ||
| 62 | + | ||
| 63 | + fseek($this->fileHandle, 0, SEEK_END); | ||
| 64 | + | ||
| 65 | + $this->cellCache[$this->currentObjectID] = array( | ||
| 66 | + 'ptr' => ftell($this->fileHandle), | ||
| 67 | + 'sz' => fwrite($this->fileHandle, serialize($this->currentObject)) | ||
| 68 | + ); | ||
| 69 | + $this->currentCellIsDirty = false; | ||
| 70 | + } | ||
| 71 | + $this->currentObjectID = $this->currentObject = null; | ||
| 72 | + } | ||
| 73 | + | ||
| 74 | + /** | ||
| 75 | + * Add or Update a cell in cache identified by coordinate address | ||
| 76 | + * | ||
| 77 | + * @param string $pCoord Coordinate address of the cell to update | ||
| 78 | + * @param PHPExcel_Cell $cell Cell to update | ||
| 79 | + * @return PHPExcel_Cell | ||
| 80 | + * @throws PHPExcel_Exception | ||
| 81 | + */ | ||
| 82 | + public function addCacheData($pCoord, PHPExcel_Cell $cell) | ||
| 83 | + { | ||
| 84 | + if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) { | ||
| 85 | + $this->storeData(); | ||
| 86 | + } | ||
| 87 | + | ||
| 88 | + $this->currentObjectID = $pCoord; | ||
| 89 | + $this->currentObject = $cell; | ||
| 90 | + $this->currentCellIsDirty = true; | ||
| 91 | + | ||
| 92 | + return $cell; | ||
| 93 | + } | ||
| 94 | + | ||
| 95 | + /** | ||
| 96 | + * Get cell at a specific coordinate | ||
| 97 | + * | ||
| 98 | + * @param string $pCoord Coordinate of the cell | ||
| 99 | + * @throws PHPExcel_Exception | ||
| 100 | + * @return PHPExcel_Cell Cell that was found, or null if not found | ||
| 101 | + */ | ||
| 102 | + public function getCacheData($pCoord) | ||
| 103 | + { | ||
| 104 | + if ($pCoord === $this->currentObjectID) { | ||
| 105 | + return $this->currentObject; | ||
| 106 | + } | ||
| 107 | + $this->storeData(); | ||
| 108 | + | ||
| 109 | + // Check if the entry that has been requested actually exists | ||
| 110 | + if (!isset($this->cellCache[$pCoord])) { | ||
| 111 | + // Return null if requested entry doesn't exist in cache | ||
| 112 | + return null; | ||
| 113 | + } | ||
| 114 | + | ||
| 115 | + // Set current entry to the requested entry | ||
| 116 | + $this->currentObjectID = $pCoord; | ||
| 117 | + fseek($this->fileHandle, $this->cellCache[$pCoord]['ptr']); | ||
| 118 | + $this->currentObject = unserialize(fread($this->fileHandle, $this->cellCache[$pCoord]['sz'])); | ||
| 119 | + // Re-attach this as the cell's parent | ||
| 120 | + $this->currentObject->attach($this); | ||
| 121 | + | ||
| 122 | + // Return requested entry | ||
| 123 | + return $this->currentObject; | ||
| 124 | + } | ||
| 125 | + | ||
| 126 | + /** | ||
| 127 | + * Get a list of all cell addresses currently held in cache | ||
| 128 | + * | ||
| 129 | + * @return string[] | ||
| 130 | + */ | ||
| 131 | + public function getCellList() | ||
| 132 | + { | ||
| 133 | + if ($this->currentObjectID !== null) { | ||
| 134 | + $this->storeData(); | ||
| 135 | + } | ||
| 136 | + | ||
| 137 | + return parent::getCellList(); | ||
| 138 | + } | ||
| 139 | + | ||
| 140 | + /** | ||
| 141 | + * Clone the cell collection | ||
| 142 | + * | ||
| 143 | + * @param PHPExcel_Worksheet $parent The new worksheet | ||
| 144 | + */ | ||
| 145 | + public function copyCellCollection(PHPExcel_Worksheet $parent) | ||
| 146 | + { | ||
| 147 | + parent::copyCellCollection($parent); | ||
| 148 | + // Get a new id for the new file name | ||
| 149 | + $baseUnique = $this->getUniqueID(); | ||
| 150 | + $newFileName = $this->cacheDirectory.'/PHPExcel.'.$baseUnique.'.cache'; | ||
| 151 | + // Copy the existing cell cache file | ||
| 152 | + copy($this->fileName, $newFileName); | ||
| 153 | + $this->fileName = $newFileName; | ||
| 154 | + // Open the copied cell cache file | ||
| 155 | + $this->fileHandle = fopen($this->fileName, 'a+'); | ||
| 156 | + } | ||
| 157 | + | ||
| 158 | + /** | ||
| 159 | + * Clear the cell collection and disconnect from our parent | ||
| 160 | + * | ||
| 161 | + */ | ||
| 162 | + public function unsetWorksheetCells() | ||
| 163 | + { | ||
| 164 | + if (!is_null($this->currentObject)) { | ||
| 165 | + $this->currentObject->detach(); | ||
| 166 | + $this->currentObject = $this->currentObjectID = null; | ||
| 167 | + } | ||
| 168 | + $this->cellCache = array(); | ||
| 169 | + | ||
| 170 | + // detach ourself from the worksheet, so that it can then delete this object successfully | ||
| 171 | + $this->parent = null; | ||
| 172 | + | ||
| 173 | + // Close down the temporary cache file | ||
| 174 | + $this->__destruct(); | ||
| 175 | + } | ||
| 176 | + | ||
| 177 | + /** | ||
| 178 | + * Initialise this new cell collection | ||
| 179 | + * | ||
| 180 | + * @param PHPExcel_Worksheet $parent The worksheet for this cell collection | ||
| 181 | + * @param array of mixed $arguments Additional initialisation arguments | ||
| 182 | + */ | ||
| 183 | + public function __construct(PHPExcel_Worksheet $parent, $arguments) | ||
| 184 | + { | ||
| 185 | + $this->cacheDirectory = ((isset($arguments['dir'])) && ($arguments['dir'] !== null)) | ||
| 186 | + ? $arguments['dir'] | ||
| 187 | + : PHPExcel_Shared_File::sys_get_temp_dir(); | ||
| 188 | + | ||
| 189 | + parent::__construct($parent); | ||
| 190 | + if (is_null($this->fileHandle)) { | ||
| 191 | + $baseUnique = $this->getUniqueID(); | ||
| 192 | + $this->fileName = $this->cacheDirectory.'/PHPExcel.'.$baseUnique.'.cache'; | ||
| 193 | + $this->fileHandle = fopen($this->fileName, 'a+'); | ||
| 194 | + } | ||
| 195 | + } | ||
| 196 | + | ||
| 197 | + /** | ||
| 198 | + * Destroy this cell collection | ||
| 199 | + */ | ||
| 200 | + public function __destruct() | ||
| 201 | + { | ||
| 202 | + if (!is_null($this->fileHandle)) { | ||
| 203 | + fclose($this->fileHandle); | ||
| 204 | + unlink($this->fileName); | ||
| 205 | + } | ||
| 206 | + $this->fileHandle = null; | ||
| 207 | + } | ||
| 208 | +} |
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +/** | ||
| 4 | + * PHPExcel_CachedObjectStorage_ICache | ||
| 5 | + * | ||
| 6 | + * Copyright (c) 2006 - 2015 PHPExcel | ||
| 7 | + * | ||
| 8 | + * This library is free software; you can redistribute it and/or | ||
| 9 | + * modify it under the terms of the GNU Lesser General Public | ||
| 10 | + * License as published by the Free Software Foundation; either | ||
| 11 | + * version 2.1 of the License, or (at your option) any later version. | ||
| 12 | + * | ||
| 13 | + * This library is distributed in the hope that it will be useful, | ||
| 14 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 16 | + * Lesser General Public License for more details. | ||
| 17 | + * | ||
| 18 | + * You should have received a copy of the GNU Lesser General Public | ||
| 19 | + * License along with this library; if not, write to the Free Software | ||
| 20 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 21 | + * | ||
| 22 | + * @category PHPExcel | ||
| 23 | + * @package PHPExcel_CachedObjectStorage | ||
| 24 | + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) | ||
| 25 | + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL | ||
| 26 | + * @version ##VERSION##, ##DATE## | ||
| 27 | + */ | ||
| 28 | +interface PHPExcel_CachedObjectStorage_ICache | ||
| 29 | +{ | ||
| 30 | + /** | ||
| 31 | + * Add or Update a cell in cache identified by coordinate address | ||
| 32 | + * | ||
| 33 | + * @param string $pCoord Coordinate address of the cell to update | ||
| 34 | + * @param PHPExcel_Cell $cell Cell to update | ||
| 35 | + * @return PHPExcel_Cell | ||
| 36 | + * @throws PHPExcel_Exception | ||
| 37 | + */ | ||
| 38 | + public function addCacheData($pCoord, PHPExcel_Cell $cell); | ||
| 39 | + | ||
| 40 | + /** | ||
| 41 | + * Add or Update a cell in cache | ||
| 42 | + * | ||
| 43 | + * @param PHPExcel_Cell $cell Cell to update | ||
| 44 | + * @return PHPExcel_Cell | ||
| 45 | + * @throws PHPExcel_Exception | ||
| 46 | + */ | ||
| 47 | + public function updateCacheData(PHPExcel_Cell $cell); | ||
| 48 | + | ||
| 49 | + /** | ||
| 50 | + * Fetch a cell from cache identified by coordinate address | ||
| 51 | + * | ||
| 52 | + * @param string $pCoord Coordinate address of the cell to retrieve | ||
| 53 | + * @return PHPExcel_Cell Cell that was found, or null if not found | ||
| 54 | + * @throws PHPExcel_Exception | ||
| 55 | + */ | ||
| 56 | + public function getCacheData($pCoord); | ||
| 57 | + | ||
| 58 | + /** | ||
| 59 | + * Delete a cell in cache identified by coordinate address | ||
| 60 | + * | ||
| 61 | + * @param string $pCoord Coordinate address of the cell to delete | ||
| 62 | + * @throws PHPExcel_Exception | ||
| 63 | + */ | ||
| 64 | + public function deleteCacheData($pCoord); | ||
| 65 | + | ||
| 66 | + /** | ||
| 67 | + * Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell? | ||
| 68 | + * | ||
| 69 | + * @param string $pCoord Coordinate address of the cell to check | ||
| 70 | + * @return boolean | ||
| 71 | + */ | ||
| 72 | + public function isDataSet($pCoord); | ||
| 73 | + | ||
| 74 | + /** | ||
| 75 | + * Get a list of all cell addresses currently held in cache | ||
| 76 | + * | ||
| 77 | + * @return string[] | ||
| 78 | + */ | ||
| 79 | + public function getCellList(); | ||
| 80 | + | ||
| 81 | + /** | ||
| 82 | + * Get the list of all cell addresses currently held in cache sorted by column and row | ||
| 83 | + * | ||
| 84 | + * @return string[] | ||
| 85 | + */ | ||
| 86 | + public function getSortedCellList(); | ||
| 87 | + | ||
| 88 | + /** | ||
| 89 | + * Clone the cell collection | ||
| 90 | + * | ||
| 91 | + * @param PHPExcel_Worksheet $parent The new worksheet | ||
| 92 | + * @return void | ||
| 93 | + */ | ||
| 94 | + public function copyCellCollection(PHPExcel_Worksheet $parent); | ||
| 95 | + | ||
| 96 | + /** | ||
| 97 | + * Identify whether the caching method is currently available | ||
| 98 | + * Some methods are dependent on the availability of certain extensions being enabled in the PHP build | ||
| 99 | + * | ||
| 100 | + * @return boolean | ||
| 101 | + */ | ||
| 102 | + public static function cacheMethodIsAvailable(); | ||
| 103 | +} |
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +/** | ||
| 4 | + * PHPExcel_CachedObjectStorage_Igbinary | ||
| 5 | + * | ||
| 6 | + * Copyright (c) 2006 - 2015 PHPExcel | ||
| 7 | + * | ||
| 8 | + * This library is free software; you can redistribute it and/or | ||
| 9 | + * modify it under the terms of the GNU Lesser General Public | ||
| 10 | + * License as published by the Free Software Foundation; either | ||
| 11 | + * version 2.1 of the License, or (at your option) any later version. | ||
| 12 | + * | ||
| 13 | + * This library is distributed in the hope that it will be useful, | ||
| 14 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 16 | + * Lesser General Public License for more details. | ||
| 17 | + * | ||
| 18 | + * You should have received a copy of the GNU Lesser General Public | ||
| 19 | + * License along with this library; if not, write to the Free Software | ||
| 20 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 21 | + * | ||
| 22 | + * @category PHPExcel | ||
| 23 | + * @package PHPExcel_CachedObjectStorage | ||
| 24 | + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) | ||
| 25 | + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL | ||
| 26 | + * @version ##VERSION##, ##DATE## | ||
| 27 | + */ | ||
| 28 | +class PHPExcel_CachedObjectStorage_Igbinary extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache | ||
| 29 | +{ | ||
| 30 | + /** | ||
| 31 | + * Store cell data in cache for the current cell object if it's "dirty", | ||
| 32 | + * and the 'nullify' the current cell object | ||
| 33 | + * | ||
| 34 | + * @return void | ||
| 35 | + * @throws PHPExcel_Exception | ||
| 36 | + */ | ||
| 37 | + protected function storeData() | ||
| 38 | + { | ||
| 39 | + if ($this->currentCellIsDirty && !empty($this->currentObjectID)) { | ||
| 40 | + $this->currentObject->detach(); | ||
| 41 | + | ||
| 42 | + $this->cellCache[$this->currentObjectID] = igbinary_serialize($this->currentObject); | ||
| 43 | + $this->currentCellIsDirty = false; | ||
| 44 | + } | ||
| 45 | + $this->currentObjectID = $this->currentObject = null; | ||
| 46 | + } // function _storeData() | ||
| 47 | + | ||
| 48 | + | ||
| 49 | + /** | ||
| 50 | + * Add or Update a cell in cache identified by coordinate address | ||
| 51 | + * | ||
| 52 | + * @param string $pCoord Coordinate address of the cell to update | ||
| 53 | + * @param PHPExcel_Cell $cell Cell to update | ||
| 54 | + * @return PHPExcel_Cell | ||
| 55 | + * @throws PHPExcel_Exception | ||
| 56 | + */ | ||
| 57 | + public function addCacheData($pCoord, PHPExcel_Cell $cell) | ||
| 58 | + { | ||
| 59 | + if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) { | ||
| 60 | + $this->storeData(); | ||
| 61 | + } | ||
| 62 | + | ||
| 63 | + $this->currentObjectID = $pCoord; | ||
| 64 | + $this->currentObject = $cell; | ||
| 65 | + $this->currentCellIsDirty = true; | ||
| 66 | + | ||
| 67 | + return $cell; | ||
| 68 | + } // function addCacheData() | ||
| 69 | + | ||
| 70 | + | ||
| 71 | + /** | ||
| 72 | + * Get cell at a specific coordinate | ||
| 73 | + * | ||
| 74 | + * @param string $pCoord Coordinate of the cell | ||
| 75 | + * @throws PHPExcel_Exception | ||
| 76 | + * @return PHPExcel_Cell Cell that was found, or null if not found | ||
| 77 | + */ | ||
| 78 | + public function getCacheData($pCoord) | ||
| 79 | + { | ||
| 80 | + if ($pCoord === $this->currentObjectID) { | ||
| 81 | + return $this->currentObject; | ||
| 82 | + } | ||
| 83 | + $this->storeData(); | ||
| 84 | + | ||
| 85 | + // Check if the entry that has been requested actually exists | ||
| 86 | + if (!isset($this->cellCache[$pCoord])) { | ||
| 87 | + // Return null if requested entry doesn't exist in cache | ||
| 88 | + return null; | ||
| 89 | + } | ||
| 90 | + | ||
| 91 | + // Set current entry to the requested entry | ||
| 92 | + $this->currentObjectID = $pCoord; | ||
| 93 | + $this->currentObject = igbinary_unserialize($this->cellCache[$pCoord]); | ||
| 94 | + // Re-attach this as the cell's parent | ||
| 95 | + $this->currentObject->attach($this); | ||
| 96 | + | ||
| 97 | + // Return requested entry | ||
| 98 | + return $this->currentObject; | ||
| 99 | + } // function getCacheData() | ||
| 100 | + | ||
| 101 | + | ||
| 102 | + /** | ||
| 103 | + * Get a list of all cell addresses currently held in cache | ||
| 104 | + * | ||
| 105 | + * @return string[] | ||
| 106 | + */ | ||
| 107 | + public function getCellList() | ||
| 108 | + { | ||
| 109 | + if ($this->currentObjectID !== null) { | ||
| 110 | + $this->storeData(); | ||
| 111 | + } | ||
| 112 | + | ||
| 113 | + return parent::getCellList(); | ||
| 114 | + } | ||
| 115 | + | ||
| 116 | + | ||
| 117 | + /** | ||
| 118 | + * Clear the cell collection and disconnect from our parent | ||
| 119 | + * | ||
| 120 | + * @return void | ||
| 121 | + */ | ||
| 122 | + public function unsetWorksheetCells() | ||
| 123 | + { | ||
| 124 | + if (!is_null($this->currentObject)) { | ||
| 125 | + $this->currentObject->detach(); | ||
| 126 | + $this->currentObject = $this->currentObjectID = null; | ||
| 127 | + } | ||
| 128 | + $this->cellCache = array(); | ||
| 129 | + | ||
| 130 | + // detach ourself from the worksheet, so that it can then delete this object successfully | ||
| 131 | + $this->parent = null; | ||
| 132 | + } // function unsetWorksheetCells() | ||
| 133 | + | ||
| 134 | + | ||
| 135 | + /** | ||
| 136 | + * Identify whether the caching method is currently available | ||
| 137 | + * Some methods are dependent on the availability of certain extensions being enabled in the PHP build | ||
| 138 | + * | ||
| 139 | + * @return boolean | ||
| 140 | + */ | ||
| 141 | + public static function cacheMethodIsAvailable() | ||
| 142 | + { | ||
| 143 | + if (!function_exists('igbinary_serialize')) { | ||
| 144 | + return false; | ||
| 145 | + } | ||
| 146 | + | ||
| 147 | + return true; | ||
| 148 | + } | ||
| 149 | +} |
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +/** | ||
| 4 | + * PHPExcel_CachedObjectStorage_Memcache | ||
| 5 | + * | ||
| 6 | + * Copyright (c) 2006 - 2015 PHPExcel | ||
| 7 | + * | ||
| 8 | + * This library is free software; you can redistribute it and/or | ||
| 9 | + * modify it under the terms of the GNU Lesser General Public | ||
| 10 | + * License as published by the Free Software Foundation; either | ||
| 11 | + * version 2.1 of the License, or (at your option) any later version. | ||
| 12 | + * | ||
| 13 | + * This library is distributed in the hope that it will be useful, | ||
| 14 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 16 | + * Lesser General Public License for more details. | ||
| 17 | + * | ||
| 18 | + * You should have received a copy of the GNU Lesser General Public | ||
| 19 | + * License along with this library; if not, write to the Free Software | ||
| 20 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 21 | + * | ||
| 22 | + * @category PHPExcel | ||
| 23 | + * @package PHPExcel_CachedObjectStorage | ||
| 24 | + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) | ||
| 25 | + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL | ||
| 26 | + * @version ##VERSION##, ##DATE## | ||
| 27 | + */ | ||
| 28 | +class PHPExcel_CachedObjectStorage_Memcache extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache | ||
| 29 | +{ | ||
| 30 | + /** | ||
| 31 | + * Prefix used to uniquely identify cache data for this worksheet | ||
| 32 | + * | ||
| 33 | + * @var string | ||
| 34 | + */ | ||
| 35 | + private $cachePrefix = null; | ||
| 36 | + | ||
| 37 | + /** | ||
| 38 | + * Cache timeout | ||
| 39 | + * | ||
| 40 | + * @var integer | ||
| 41 | + */ | ||
| 42 | + private $cacheTime = 600; | ||
| 43 | + | ||
| 44 | + /** | ||
| 45 | + * Memcache interface | ||
| 46 | + * | ||
| 47 | + * @var resource | ||
| 48 | + */ | ||
| 49 | + private $memcache = null; | ||
| 50 | + | ||
| 51 | + | ||
| 52 | + /** | ||
| 53 | + * Store cell data in cache for the current cell object if it's "dirty", | ||
| 54 | + * and the 'nullify' the current cell object | ||
| 55 | + * | ||
| 56 | + * @return void | ||
| 57 | + * @throws PHPExcel_Exception | ||
| 58 | + */ | ||
| 59 | + protected function storeData() | ||
| 60 | + { | ||
| 61 | + if ($this->currentCellIsDirty && !empty($this->currentObjectID)) { | ||
| 62 | + $this->currentObject->detach(); | ||
| 63 | + | ||
| 64 | + $obj = serialize($this->currentObject); | ||
| 65 | + if (!$this->memcache->replace($this->cachePrefix . $this->currentObjectID . '.cache', $obj, null, $this->cacheTime)) { | ||
| 66 | + if (!$this->memcache->add($this->cachePrefix . $this->currentObjectID . '.cache', $obj, null, $this->cacheTime)) { | ||
| 67 | + $this->__destruct(); | ||
| 68 | + throw new PHPExcel_Exception("Failed to store cell {$this->currentObjectID} in MemCache"); | ||
| 69 | + } | ||
| 70 | + } | ||
| 71 | + $this->currentCellIsDirty = false; | ||
| 72 | + } | ||
| 73 | + $this->currentObjectID = $this->currentObject = null; | ||
| 74 | + } // function _storeData() | ||
| 75 | + | ||
| 76 | + | ||
| 77 | + /** | ||
| 78 | + * Add or Update a cell in cache identified by coordinate address | ||
| 79 | + * | ||
| 80 | + * @param string $pCoord Coordinate address of the cell to update | ||
| 81 | + * @param PHPExcel_Cell $cell Cell to update | ||
| 82 | + * @return PHPExcel_Cell | ||
| 83 | + * @throws PHPExcel_Exception | ||
| 84 | + */ | ||
| 85 | + public function addCacheData($pCoord, PHPExcel_Cell $cell) | ||
| 86 | + { | ||
| 87 | + if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) { | ||
| 88 | + $this->storeData(); | ||
| 89 | + } | ||
| 90 | + $this->cellCache[$pCoord] = true; | ||
| 91 | + | ||
| 92 | + $this->currentObjectID = $pCoord; | ||
| 93 | + $this->currentObject = $cell; | ||
| 94 | + $this->currentCellIsDirty = true; | ||
| 95 | + | ||
| 96 | + return $cell; | ||
| 97 | + } // function addCacheData() | ||
| 98 | + | ||
| 99 | + | ||
| 100 | + /** | ||
| 101 | + * Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell? | ||
| 102 | + * | ||
| 103 | + * @param string $pCoord Coordinate address of the cell to check | ||
| 104 | + * @return boolean | ||
| 105 | + * @return boolean | ||
| 106 | + */ | ||
| 107 | + public function isDataSet($pCoord) | ||
| 108 | + { | ||
| 109 | + // Check if the requested entry is the current object, or exists in the cache | ||
| 110 | + if (parent::isDataSet($pCoord)) { | ||
| 111 | + if ($this->currentObjectID == $pCoord) { | ||
| 112 | + return true; | ||
| 113 | + } | ||
| 114 | + // Check if the requested entry still exists in Memcache | ||
| 115 | + $success = $this->memcache->get($this->cachePrefix.$pCoord.'.cache'); | ||
| 116 | + if ($success === false) { | ||
| 117 | + // Entry no longer exists in Memcache, so clear it from the cache array | ||
| 118 | + parent::deleteCacheData($pCoord); | ||
| 119 | + throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in MemCache'); | ||
| 120 | + } | ||
| 121 | + return true; | ||
| 122 | + } | ||
| 123 | + return false; | ||
| 124 | + } | ||
| 125 | + | ||
| 126 | + | ||
| 127 | + /** | ||
| 128 | + * Get cell at a specific coordinate | ||
| 129 | + * | ||
| 130 | + * @param string $pCoord Coordinate of the cell | ||
| 131 | + * @throws PHPExcel_Exception | ||
| 132 | + * @return PHPExcel_Cell Cell that was found, or null if not found | ||
| 133 | + */ | ||
| 134 | + public function getCacheData($pCoord) | ||
| 135 | + { | ||
| 136 | + if ($pCoord === $this->currentObjectID) { | ||
| 137 | + return $this->currentObject; | ||
| 138 | + } | ||
| 139 | + $this->storeData(); | ||
| 140 | + | ||
| 141 | + // Check if the entry that has been requested actually exists | ||
| 142 | + if (parent::isDataSet($pCoord)) { | ||
| 143 | + $obj = $this->memcache->get($this->cachePrefix . $pCoord . '.cache'); | ||
| 144 | + if ($obj === false) { | ||
| 145 | + // Entry no longer exists in Memcache, so clear it from the cache array | ||
| 146 | + parent::deleteCacheData($pCoord); | ||
| 147 | + throw new PHPExcel_Exception("Cell entry {$pCoord} no longer exists in MemCache"); | ||
| 148 | + } | ||
| 149 | + } else { | ||
| 150 | + // Return null if requested entry doesn't exist in cache | ||
| 151 | + return null; | ||
| 152 | + } | ||
| 153 | + | ||
| 154 | + // Set current entry to the requested entry | ||
| 155 | + $this->currentObjectID = $pCoord; | ||
| 156 | + $this->currentObject = unserialize($obj); | ||
| 157 | + // Re-attach this as the cell's parent | ||
| 158 | + $this->currentObject->attach($this); | ||
| 159 | + | ||
| 160 | + // Return requested entry | ||
| 161 | + return $this->currentObject; | ||
| 162 | + } | ||
| 163 | + | ||
| 164 | + /** | ||
| 165 | + * Get a list of all cell addresses currently held in cache | ||
| 166 | + * | ||
| 167 | + * @return string[] | ||
| 168 | + */ | ||
| 169 | + public function getCellList() | ||
| 170 | + { | ||
| 171 | + if ($this->currentObjectID !== null) { | ||
| 172 | + $this->storeData(); | ||
| 173 | + } | ||
| 174 | + | ||
| 175 | + return parent::getCellList(); | ||
| 176 | + } | ||
| 177 | + | ||
| 178 | + /** | ||
| 179 | + * Delete a cell in cache identified by coordinate address | ||
| 180 | + * | ||
| 181 | + * @param string $pCoord Coordinate address of the cell to delete | ||
| 182 | + * @throws PHPExcel_Exception | ||
| 183 | + */ | ||
| 184 | + public function deleteCacheData($pCoord) | ||
| 185 | + { | ||
| 186 | + // Delete the entry from Memcache | ||
| 187 | + $this->memcache->delete($this->cachePrefix . $pCoord . '.cache'); | ||
| 188 | + | ||
| 189 | + // Delete the entry from our cell address array | ||
| 190 | + parent::deleteCacheData($pCoord); | ||
| 191 | + } | ||
| 192 | + | ||
| 193 | + /** | ||
| 194 | + * Clone the cell collection | ||
| 195 | + * | ||
| 196 | + * @param PHPExcel_Worksheet $parent The new worksheet | ||
| 197 | + * @return void | ||
| 198 | + */ | ||
| 199 | + public function copyCellCollection(PHPExcel_Worksheet $parent) | ||
| 200 | + { | ||
| 201 | + parent::copyCellCollection($parent); | ||
| 202 | + // Get a new id for the new file name | ||
| 203 | + $baseUnique = $this->getUniqueID(); | ||
| 204 | + $newCachePrefix = substr(md5($baseUnique), 0, 8) . '.'; | ||
| 205 | + $cacheList = $this->getCellList(); | ||
| 206 | + foreach ($cacheList as $cellID) { | ||
| 207 | + if ($cellID != $this->currentObjectID) { | ||
| 208 | + $obj = $this->memcache->get($this->cachePrefix.$cellID.'.cache'); | ||
| 209 | + if ($obj === false) { | ||
| 210 | + // Entry no longer exists in Memcache, so clear it from the cache array | ||
| 211 | + parent::deleteCacheData($cellID); | ||
| 212 | + throw new PHPExcel_Exception("Cell entry {$cellID} no longer exists in MemCache"); | ||
| 213 | + } | ||
| 214 | + if (!$this->memcache->add($newCachePrefix . $cellID . '.cache', $obj, null, $this->cacheTime)) { | ||
| 215 | + $this->__destruct(); | ||
| 216 | + throw new PHPExcel_Exception("Failed to store cell {$cellID} in MemCache"); | ||
| 217 | + } | ||
| 218 | + } | ||
| 219 | + } | ||
| 220 | + $this->cachePrefix = $newCachePrefix; | ||
| 221 | + } | ||
| 222 | + | ||
| 223 | + /** | ||
| 224 | + * Clear the cell collection and disconnect from our parent | ||
| 225 | + * | ||
| 226 | + * @return void | ||
| 227 | + */ | ||
| 228 | + public function unsetWorksheetCells() | ||
| 229 | + { | ||
| 230 | + if (!is_null($this->currentObject)) { | ||
| 231 | + $this->currentObject->detach(); | ||
| 232 | + $this->currentObject = $this->currentObjectID = null; | ||
| 233 | + } | ||
| 234 | + | ||
| 235 | + // Flush the Memcache cache | ||
| 236 | + $this->__destruct(); | ||
| 237 | + | ||
| 238 | + $this->cellCache = array(); | ||
| 239 | + | ||
| 240 | + // detach ourself from the worksheet, so that it can then delete this object successfully | ||
| 241 | + $this->parent = null; | ||
| 242 | + } | ||
| 243 | + | ||
| 244 | + /** | ||
| 245 | + * Initialise this new cell collection | ||
| 246 | + * | ||
| 247 | + * @param PHPExcel_Worksheet $parent The worksheet for this cell collection | ||
| 248 | + * @param array of mixed $arguments Additional initialisation arguments | ||
| 249 | + */ | ||
| 250 | + public function __construct(PHPExcel_Worksheet $parent, $arguments) | ||
| 251 | + { | ||
| 252 | + $memcacheServer = (isset($arguments['memcacheServer'])) ? $arguments['memcacheServer'] : 'localhost'; | ||
| 253 | + $memcachePort = (isset($arguments['memcachePort'])) ? $arguments['memcachePort'] : 11211; | ||
| 254 | + $cacheTime = (isset($arguments['cacheTime'])) ? $arguments['cacheTime'] : 600; | ||
| 255 | + | ||
| 256 | + if (is_null($this->cachePrefix)) { | ||
| 257 | + $baseUnique = $this->getUniqueID(); | ||
| 258 | + $this->cachePrefix = substr(md5($baseUnique), 0, 8) . '.'; | ||
| 259 | + | ||
| 260 | + // Set a new Memcache object and connect to the Memcache server | ||
| 261 | + $this->memcache = new Memcache(); | ||
| 262 | + if (!$this->memcache->addServer($memcacheServer, $memcachePort, false, 50, 5, 5, true, array($this, 'failureCallback'))) { | ||
| 263 | + throw new PHPExcel_Exception("Could not connect to MemCache server at {$memcacheServer}:{$memcachePort}"); | ||
| 264 | + } | ||
| 265 | + $this->cacheTime = $cacheTime; | ||
| 266 | + | ||
| 267 | + parent::__construct($parent); | ||
| 268 | + } | ||
| 269 | + } | ||
| 270 | + | ||
| 271 | + /** | ||
| 272 | + * Memcache error handler | ||
| 273 | + * | ||
| 274 | + * @param string $host Memcache server | ||
| 275 | + * @param integer $port Memcache port | ||
| 276 | + * @throws PHPExcel_Exception | ||
| 277 | + */ | ||
| 278 | + public function failureCallback($host, $port) | ||
| 279 | + { | ||
| 280 | + throw new PHPExcel_Exception("memcache {$host}:{$port} failed"); | ||
| 281 | + } | ||
| 282 | + | ||
| 283 | + /** | ||
| 284 | + * Destroy this cell collection | ||
| 285 | + */ | ||
| 286 | + public function __destruct() | ||
| 287 | + { | ||
| 288 | + $cacheList = $this->getCellList(); | ||
| 289 | + foreach ($cacheList as $cellID) { | ||
| 290 | + $this->memcache->delete($this->cachePrefix.$cellID . '.cache'); | ||
| 291 | + } | ||
| 292 | + } | ||
| 293 | + | ||
| 294 | + /** | ||
| 295 | + * Identify whether the caching method is currently available | ||
| 296 | + * Some methods are dependent on the availability of certain extensions being enabled in the PHP build | ||
| 297 | + * | ||
| 298 | + * @return boolean | ||
| 299 | + */ | ||
| 300 | + public static function cacheMethodIsAvailable() | ||
| 301 | + { | ||
| 302 | + if (!function_exists('memcache_add')) { | ||
| 303 | + return false; | ||
| 304 | + } | ||
| 305 | + | ||
| 306 | + return true; | ||
| 307 | + } | ||
| 308 | +} |
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +/** | ||
| 4 | + * PHPExcel_CachedObjectStorage_Memory | ||
| 5 | + * | ||
| 6 | + * Copyright (c) 2006 - 2015 PHPExcel | ||
| 7 | + * | ||
| 8 | + * This library is free software; you can redistribute it and/or | ||
| 9 | + * modify it under the terms of the GNU Lesser General Public | ||
| 10 | + * License as published by the Free Software Foundation; either | ||
| 11 | + * version 2.1 of the License, or (at your option) any later version. | ||
| 12 | + * | ||
| 13 | + * This library is distributed in the hope that it will be useful, | ||
| 14 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 16 | + * Lesser General Public License for more details. | ||
| 17 | + * | ||
| 18 | + * You should have received a copy of the GNU Lesser General Public | ||
| 19 | + * License along with this library; if not, write to the Free Software | ||
| 20 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 21 | + * | ||
| 22 | + * @category PHPExcel | ||
| 23 | + * @package PHPExcel_CachedObjectStorage | ||
| 24 | + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) | ||
| 25 | + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL | ||
| 26 | + * @version ##VERSION##, ##DATE## | ||
| 27 | + */ | ||
| 28 | +class PHPExcel_CachedObjectStorage_Memory extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache | ||
| 29 | +{ | ||
| 30 | + /** | ||
| 31 | + * Dummy method callable from CacheBase, but unused by Memory cache | ||
| 32 | + * | ||
| 33 | + * @return void | ||
| 34 | + */ | ||
| 35 | + protected function storeData() | ||
| 36 | + { | ||
| 37 | + } | ||
| 38 | + | ||
| 39 | + /** | ||
| 40 | + * Add or Update a cell in cache identified by coordinate address | ||
| 41 | + * | ||
| 42 | + * @param string $pCoord Coordinate address of the cell to update | ||
| 43 | + * @param PHPExcel_Cell $cell Cell to update | ||
| 44 | + * @return PHPExcel_Cell | ||
| 45 | + * @throws PHPExcel_Exception | ||
| 46 | + */ | ||
| 47 | + public function addCacheData($pCoord, PHPExcel_Cell $cell) | ||
| 48 | + { | ||
| 49 | + $this->cellCache[$pCoord] = $cell; | ||
| 50 | + | ||
| 51 | + // Set current entry to the new/updated entry | ||
| 52 | + $this->currentObjectID = $pCoord; | ||
| 53 | + | ||
| 54 | + return $cell; | ||
| 55 | + } | ||
| 56 | + | ||
| 57 | + | ||
| 58 | + /** | ||
| 59 | + * Get cell at a specific coordinate | ||
| 60 | + * | ||
| 61 | + * @param string $pCoord Coordinate of the cell | ||
| 62 | + * @throws PHPExcel_Exception | ||
| 63 | + * @return PHPExcel_Cell Cell that was found, or null if not found | ||
| 64 | + */ | ||
| 65 | + public function getCacheData($pCoord) | ||
| 66 | + { | ||
| 67 | + // Check if the entry that has been requested actually exists | ||
| 68 | + if (!isset($this->cellCache[$pCoord])) { | ||
| 69 | + $this->currentObjectID = null; | ||
| 70 | + // Return null if requested entry doesn't exist in cache | ||
| 71 | + return null; | ||
| 72 | + } | ||
| 73 | + | ||
| 74 | + // Set current entry to the requested entry | ||
| 75 | + $this->currentObjectID = $pCoord; | ||
| 76 | + | ||
| 77 | + // Return requested entry | ||
| 78 | + return $this->cellCache[$pCoord]; | ||
| 79 | + } | ||
| 80 | + | ||
| 81 | + | ||
| 82 | + /** | ||
| 83 | + * Clone the cell collection | ||
| 84 | + * | ||
| 85 | + * @param PHPExcel_Worksheet $parent The new worksheet | ||
| 86 | + */ | ||
| 87 | + public function copyCellCollection(PHPExcel_Worksheet $parent) | ||
| 88 | + { | ||
| 89 | + parent::copyCellCollection($parent); | ||
| 90 | + | ||
| 91 | + $newCollection = array(); | ||
| 92 | + foreach ($this->cellCache as $k => &$cell) { | ||
| 93 | + $newCollection[$k] = clone $cell; | ||
| 94 | + $newCollection[$k]->attach($this); | ||
| 95 | + } | ||
| 96 | + | ||
| 97 | + $this->cellCache = $newCollection; | ||
| 98 | + } | ||
| 99 | + | ||
| 100 | + /** | ||
| 101 | + * Clear the cell collection and disconnect from our parent | ||
| 102 | + * | ||
| 103 | + */ | ||
| 104 | + public function unsetWorksheetCells() | ||
| 105 | + { | ||
| 106 | + // Because cells are all stored as intact objects in memory, we need to detach each one from the parent | ||
| 107 | + foreach ($this->cellCache as $k => &$cell) { | ||
| 108 | + $cell->detach(); | ||
| 109 | + $this->cellCache[$k] = null; | ||
| 110 | + } | ||
| 111 | + unset($cell); | ||
| 112 | + | ||
| 113 | + $this->cellCache = array(); | ||
| 114 | + | ||
| 115 | + // detach ourself from the worksheet, so that it can then delete this object successfully | ||
| 116 | + $this->parent = null; | ||
| 117 | + } | ||
| 118 | +} |
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +/** | ||
| 4 | + * PHPExcel_CachedObjectStorage_MemoryGZip | ||
| 5 | + * | ||
| 6 | + * Copyright (c) 2006 - 2015 PHPExcel | ||
| 7 | + * | ||
| 8 | + * This library is free software; you can redistribute it and/or | ||
| 9 | + * modify it under the terms of the GNU Lesser General Public | ||
| 10 | + * License as published by the Free Software Foundation; either | ||
| 11 | + * version 2.1 of the License, or (at your option) any later version. | ||
| 12 | + * | ||
| 13 | + * This library is distributed in the hope that it will be useful, | ||
| 14 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 16 | + * Lesser General Public License for more details. | ||
| 17 | + * | ||
| 18 | + * You should have received a copy of the GNU Lesser General Public | ||
| 19 | + * License along with this library; if not, write to the Free Software | ||
| 20 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 21 | + * | ||
| 22 | + * @category PHPExcel | ||
| 23 | + * @package PHPExcel_CachedObjectStorage | ||
| 24 | + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) | ||
| 25 | + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL | ||
| 26 | + * @version ##VERSION##, ##DATE## | ||
| 27 | + */ | ||
| 28 | +class PHPExcel_CachedObjectStorage_MemoryGZip extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache | ||
| 29 | +{ | ||
| 30 | + /** | ||
| 31 | + * Store cell data in cache for the current cell object if it's "dirty", | ||
| 32 | + * and the 'nullify' the current cell object | ||
| 33 | + * | ||
| 34 | + * @return void | ||
| 35 | + * @throws PHPExcel_Exception | ||
| 36 | + */ | ||
| 37 | + protected function storeData() | ||
| 38 | + { | ||
| 39 | + if ($this->currentCellIsDirty && !empty($this->currentObjectID)) { | ||
| 40 | + $this->currentObject->detach(); | ||
| 41 | + | ||
| 42 | + $this->cellCache[$this->currentObjectID] = gzdeflate(serialize($this->currentObject)); | ||
| 43 | + $this->currentCellIsDirty = false; | ||
| 44 | + } | ||
| 45 | + $this->currentObjectID = $this->currentObject = null; | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | + | ||
| 49 | + /** | ||
| 50 | + * Add or Update a cell in cache identified by coordinate address | ||
| 51 | + * | ||
| 52 | + * @param string $pCoord Coordinate address of the cell to update | ||
| 53 | + * @param PHPExcel_Cell $cell Cell to update | ||
| 54 | + * @return PHPExcel_Cell | ||
| 55 | + * @throws PHPExcel_Exception | ||
| 56 | + */ | ||
| 57 | + public function addCacheData($pCoord, PHPExcel_Cell $cell) | ||
| 58 | + { | ||
| 59 | + if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) { | ||
| 60 | + $this->storeData(); | ||
| 61 | + } | ||
| 62 | + | ||
| 63 | + $this->currentObjectID = $pCoord; | ||
| 64 | + $this->currentObject = $cell; | ||
| 65 | + $this->currentCellIsDirty = true; | ||
| 66 | + | ||
| 67 | + return $cell; | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + | ||
| 71 | + /** | ||
| 72 | + * Get cell at a specific coordinate | ||
| 73 | + * | ||
| 74 | + * @param string $pCoord Coordinate of the cell | ||
| 75 | + * @throws PHPExcel_Exception | ||
| 76 | + * @return PHPExcel_Cell Cell that was found, or null if not found | ||
| 77 | + */ | ||
| 78 | + public function getCacheData($pCoord) | ||
| 79 | + { | ||
| 80 | + if ($pCoord === $this->currentObjectID) { | ||
| 81 | + return $this->currentObject; | ||
| 82 | + } | ||
| 83 | + $this->storeData(); | ||
| 84 | + | ||
| 85 | + // Check if the entry that has been requested actually exists | ||
| 86 | + if (!isset($this->cellCache[$pCoord])) { | ||
| 87 | + // Return null if requested entry doesn't exist in cache | ||
| 88 | + return null; | ||
| 89 | + } | ||
| 90 | + | ||
| 91 | + // Set current entry to the requested entry | ||
| 92 | + $this->currentObjectID = $pCoord; | ||
| 93 | + $this->currentObject = unserialize(gzinflate($this->cellCache[$pCoord])); | ||
| 94 | + // Re-attach this as the cell's parent | ||
| 95 | + $this->currentObject->attach($this); | ||
| 96 | + | ||
| 97 | + // Return requested entry | ||
| 98 | + return $this->currentObject; | ||
| 99 | + } | ||
| 100 | + | ||
| 101 | + | ||
| 102 | + /** | ||
| 103 | + * Get a list of all cell addresses currently held in cache | ||
| 104 | + * | ||
| 105 | + * @return string[] | ||
| 106 | + */ | ||
| 107 | + public function getCellList() | ||
| 108 | + { | ||
| 109 | + if ($this->currentObjectID !== null) { | ||
| 110 | + $this->storeData(); | ||
| 111 | + } | ||
| 112 | + | ||
| 113 | + return parent::getCellList(); | ||
| 114 | + } | ||
| 115 | + | ||
| 116 | + | ||
| 117 | + /** | ||
| 118 | + * Clear the cell collection and disconnect from our parent | ||
| 119 | + * | ||
| 120 | + * @return void | ||
| 121 | + */ | ||
| 122 | + public function unsetWorksheetCells() | ||
| 123 | + { | ||
| 124 | + if (!is_null($this->currentObject)) { | ||
| 125 | + $this->currentObject->detach(); | ||
| 126 | + $this->currentObject = $this->currentObjectID = null; | ||
| 127 | + } | ||
| 128 | + $this->cellCache = array(); | ||
| 129 | + | ||
| 130 | + // detach ourself from the worksheet, so that it can then delete this object successfully | ||
| 131 | + $this->parent = null; | ||
| 132 | + } | ||
| 133 | +} |
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +/** | ||
| 4 | + * PHPExcel_CachedObjectStorage_MemorySerialized | ||
| 5 | + * | ||
| 6 | + * Copyright (c) 2006 - 2015 PHPExcel | ||
| 7 | + * | ||
| 8 | + * This library is free software; you can redistribute it and/or | ||
| 9 | + * modify it under the terms of the GNU Lesser General Public | ||
| 10 | + * License as published by the Free Software Foundation; either | ||
| 11 | + * version 2.1 of the License, or (at your option) any later version. | ||
| 12 | + * | ||
| 13 | + * This library is distributed in the hope that it will be useful, | ||
| 14 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 16 | + * Lesser General Public License for more details. | ||
| 17 | + * | ||
| 18 | + * You should have received a copy of the GNU Lesser General Public | ||
| 19 | + * License along with this library; if not, write to the Free Software | ||
| 20 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 21 | + * | ||
| 22 | + * @category PHPExcel | ||
| 23 | + * @package PHPExcel_CachedObjectStorage | ||
| 24 | + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) | ||
| 25 | + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL | ||
| 26 | + * @version ##VERSION##, ##DATE## | ||
| 27 | + */ | ||
| 28 | +class PHPExcel_CachedObjectStorage_MemorySerialized extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache | ||
| 29 | +{ | ||
| 30 | + /** | ||
| 31 | + * Store cell data in cache for the current cell object if it's "dirty", | ||
| 32 | + * and the 'nullify' the current cell object | ||
| 33 | + * | ||
| 34 | + * @return void | ||
| 35 | + * @throws PHPExcel_Exception | ||
| 36 | + */ | ||
| 37 | + protected function storeData() | ||
| 38 | + { | ||
| 39 | + if ($this->currentCellIsDirty && !empty($this->currentObjectID)) { | ||
| 40 | + $this->currentObject->detach(); | ||
| 41 | + | ||
| 42 | + $this->cellCache[$this->currentObjectID] = serialize($this->currentObject); | ||
| 43 | + $this->currentCellIsDirty = false; | ||
| 44 | + } | ||
| 45 | + $this->currentObjectID = $this->currentObject = null; | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | + /** | ||
| 49 | + * Add or Update a cell in cache identified by coordinate address | ||
| 50 | + * | ||
| 51 | + * @param string $pCoord Coordinate address of the cell to update | ||
| 52 | + * @param PHPExcel_Cell $cell Cell to update | ||
| 53 | + * @return PHPExcel_Cell | ||
| 54 | + * @throws PHPExcel_Exception | ||
| 55 | + */ | ||
| 56 | + public function addCacheData($pCoord, PHPExcel_Cell $cell) | ||
| 57 | + { | ||
| 58 | + if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) { | ||
| 59 | + $this->storeData(); | ||
| 60 | + } | ||
| 61 | + | ||
| 62 | + $this->currentObjectID = $pCoord; | ||
| 63 | + $this->currentObject = $cell; | ||
| 64 | + $this->currentCellIsDirty = true; | ||
| 65 | + | ||
| 66 | + return $cell; | ||
| 67 | + } | ||
| 68 | + | ||
| 69 | + /** | ||
| 70 | + * Get cell at a specific coordinate | ||
| 71 | + * | ||
| 72 | + * @param string $pCoord Coordinate of the cell | ||
| 73 | + * @throws PHPExcel_Exception | ||
| 74 | + * @return PHPExcel_Cell Cell that was found, or null if not found | ||
| 75 | + */ | ||
| 76 | + public function getCacheData($pCoord) | ||
| 77 | + { | ||
| 78 | + if ($pCoord === $this->currentObjectID) { | ||
| 79 | + return $this->currentObject; | ||
| 80 | + } | ||
| 81 | + $this->storeData(); | ||
| 82 | + | ||
| 83 | + // Check if the entry that has been requested actually exists | ||
| 84 | + if (!isset($this->cellCache[$pCoord])) { | ||
| 85 | + // Return null if requested entry doesn't exist in cache | ||
| 86 | + return null; | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + // Set current entry to the requested entry | ||
| 90 | + $this->currentObjectID = $pCoord; | ||
| 91 | + $this->currentObject = unserialize($this->cellCache[$pCoord]); | ||
| 92 | + // Re-attach this as the cell's parent | ||
| 93 | + $this->currentObject->attach($this); | ||
| 94 | + | ||
| 95 | + // Return requested entry | ||
| 96 | + return $this->currentObject; | ||
| 97 | + } | ||
| 98 | + | ||
| 99 | + /** | ||
| 100 | + * Get a list of all cell addresses currently held in cache | ||
| 101 | + * | ||
| 102 | + * @return string[] | ||
| 103 | + */ | ||
| 104 | + public function getCellList() | ||
| 105 | + { | ||
| 106 | + if ($this->currentObjectID !== null) { | ||
| 107 | + $this->storeData(); | ||
| 108 | + } | ||
| 109 | + | ||
| 110 | + return parent::getCellList(); | ||
| 111 | + } | ||
| 112 | + | ||
| 113 | + /** | ||
| 114 | + * Clear the cell collection and disconnect from our parent | ||
| 115 | + * | ||
| 116 | + * @return void | ||
| 117 | + */ | ||
| 118 | + public function unsetWorksheetCells() | ||
| 119 | + { | ||
| 120 | + if (!is_null($this->currentObject)) { | ||
| 121 | + $this->currentObject->detach(); | ||
| 122 | + $this->currentObject = $this->currentObjectID = null; | ||
| 123 | + } | ||
| 124 | + $this->cellCache = array(); | ||
| 125 | + | ||
| 126 | + // detach ourself from the worksheet, so that it can then delete this object successfully | ||
| 127 | + $this->parent = null; | ||
| 128 | + } | ||
| 129 | +} |
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +/** | ||
| 4 | + * PHPExcel_CachedObjectStorage_PHPTemp | ||
| 5 | + * | ||
| 6 | + * Copyright (c) 2006 - 2015 PHPExcel | ||
| 7 | + * | ||
| 8 | + * This library is free software; you can redistribute it and/or | ||
| 9 | + * modify it under the terms of the GNU Lesser General Public | ||
| 10 | + * License as published by the Free Software Foundation; either | ||
| 11 | + * version 2.1 of the License, or (at your option) any later version. | ||
| 12 | + * | ||
| 13 | + * This library is distributed in the hope that it will be useful, | ||
| 14 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 16 | + * Lesser General Public License for more details. | ||
| 17 | + * | ||
| 18 | + * You should have received a copy of the GNU Lesser General Public | ||
| 19 | + * License along with this library; if not, write to the Free Software | ||
| 20 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 21 | + * | ||
| 22 | + * @category PHPExcel | ||
| 23 | + * @package PHPExcel_CachedObjectStorage | ||
| 24 | + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) | ||
| 25 | + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL | ||
| 26 | + * @version ##VERSION##, ##DATE## | ||
| 27 | + */ | ||
| 28 | +class PHPExcel_CachedObjectStorage_PHPTemp extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache | ||
| 29 | +{ | ||
| 30 | + /** | ||
| 31 | + * Name of the file for this cache | ||
| 32 | + * | ||
| 33 | + * @var string | ||
| 34 | + */ | ||
| 35 | + private $fileHandle = null; | ||
| 36 | + | ||
| 37 | + /** | ||
| 38 | + * Memory limit to use before reverting to file cache | ||
| 39 | + * | ||
| 40 | + * @var integer | ||
| 41 | + */ | ||
| 42 | + private $memoryCacheSize = null; | ||
| 43 | + | ||
| 44 | + /** | ||
| 45 | + * Store cell data in cache for the current cell object if it's "dirty", | ||
| 46 | + * and the 'nullify' the current cell object | ||
| 47 | + * | ||
| 48 | + * @return void | ||
| 49 | + * @throws PHPExcel_Exception | ||
| 50 | + */ | ||
| 51 | + protected function storeData() | ||
| 52 | + { | ||
| 53 | + if ($this->currentCellIsDirty && !empty($this->currentObjectID)) { | ||
| 54 | + $this->currentObject->detach(); | ||
| 55 | + | ||
| 56 | + fseek($this->fileHandle, 0, SEEK_END); | ||
| 57 | + | ||
| 58 | + $this->cellCache[$this->currentObjectID] = array( | ||
| 59 | + 'ptr' => ftell($this->fileHandle), | ||
| 60 | + 'sz' => fwrite($this->fileHandle, serialize($this->currentObject)) | ||
| 61 | + ); | ||
| 62 | + $this->currentCellIsDirty = false; | ||
| 63 | + } | ||
| 64 | + $this->currentObjectID = $this->currentObject = null; | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | + | ||
| 68 | + /** | ||
| 69 | + * Add or Update a cell in cache identified by coordinate address | ||
| 70 | + * | ||
| 71 | + * @param string $pCoord Coordinate address of the cell to update | ||
| 72 | + * @param PHPExcel_Cell $cell Cell to update | ||
| 73 | + * @return PHPExcel_Cell | ||
| 74 | + * @throws PHPExcel_Exception | ||
| 75 | + */ | ||
| 76 | + public function addCacheData($pCoord, PHPExcel_Cell $cell) | ||
| 77 | + { | ||
| 78 | + if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) { | ||
| 79 | + $this->storeData(); | ||
| 80 | + } | ||
| 81 | + | ||
| 82 | + $this->currentObjectID = $pCoord; | ||
| 83 | + $this->currentObject = $cell; | ||
| 84 | + $this->currentCellIsDirty = true; | ||
| 85 | + | ||
| 86 | + return $cell; | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + | ||
| 90 | + /** | ||
| 91 | + * Get cell at a specific coordinate | ||
| 92 | + * | ||
| 93 | + * @param string $pCoord Coordinate of the cell | ||
| 94 | + * @throws PHPExcel_Exception | ||
| 95 | + * @return PHPExcel_Cell Cell that was found, or null if not found | ||
| 96 | + */ | ||
| 97 | + public function getCacheData($pCoord) | ||
| 98 | + { | ||
| 99 | + if ($pCoord === $this->currentObjectID) { | ||
| 100 | + return $this->currentObject; | ||
| 101 | + } | ||
| 102 | + $this->storeData(); | ||
| 103 | + | ||
| 104 | + // Check if the entry that has been requested actually exists | ||
| 105 | + if (!isset($this->cellCache[$pCoord])) { | ||
| 106 | + // Return null if requested entry doesn't exist in cache | ||
| 107 | + return null; | ||
| 108 | + } | ||
| 109 | + | ||
| 110 | + // Set current entry to the requested entry | ||
| 111 | + $this->currentObjectID = $pCoord; | ||
| 112 | + fseek($this->fileHandle, $this->cellCache[$pCoord]['ptr']); | ||
| 113 | + $this->currentObject = unserialize(fread($this->fileHandle, $this->cellCache[$pCoord]['sz'])); | ||
| 114 | + // Re-attach this as the cell's parent | ||
| 115 | + $this->currentObject->attach($this); | ||
| 116 | + | ||
| 117 | + // Return requested entry | ||
| 118 | + return $this->currentObject; | ||
| 119 | + } | ||
| 120 | + | ||
| 121 | + /** | ||
| 122 | + * Get a list of all cell addresses currently held in cache | ||
| 123 | + * | ||
| 124 | + * @return string[] | ||
| 125 | + */ | ||
| 126 | + public function getCellList() | ||
| 127 | + { | ||
| 128 | + if ($this->currentObjectID !== null) { | ||
| 129 | + $this->storeData(); | ||
| 130 | + } | ||
| 131 | + | ||
| 132 | + return parent::getCellList(); | ||
| 133 | + } | ||
| 134 | + | ||
| 135 | + /** | ||
| 136 | + * Clone the cell collection | ||
| 137 | + * | ||
| 138 | + * @param PHPExcel_Worksheet $parent The new worksheet | ||
| 139 | + * @return void | ||
| 140 | + */ | ||
| 141 | + public function copyCellCollection(PHPExcel_Worksheet $parent) | ||
| 142 | + { | ||
| 143 | + parent::copyCellCollection($parent); | ||
| 144 | + // Open a new stream for the cell cache data | ||
| 145 | + $newFileHandle = fopen('php://temp/maxmemory:' . $this->memoryCacheSize, 'a+'); | ||
| 146 | + // Copy the existing cell cache data to the new stream | ||
| 147 | + fseek($this->fileHandle, 0); | ||
| 148 | + while (!feof($this->fileHandle)) { | ||
| 149 | + fwrite($newFileHandle, fread($this->fileHandle, 1024)); | ||
| 150 | + } | ||
| 151 | + $this->fileHandle = $newFileHandle; | ||
| 152 | + } | ||
| 153 | + | ||
| 154 | + /** | ||
| 155 | + * Clear the cell collection and disconnect from our parent | ||
| 156 | + * | ||
| 157 | + * @return void | ||
| 158 | + */ | ||
| 159 | + public function unsetWorksheetCells() | ||
| 160 | + { | ||
| 161 | + if (!is_null($this->currentObject)) { | ||
| 162 | + $this->currentObject->detach(); | ||
| 163 | + $this->currentObject = $this->currentObjectID = null; | ||
| 164 | + } | ||
| 165 | + $this->cellCache = array(); | ||
| 166 | + | ||
| 167 | + // detach ourself from the worksheet, so that it can then delete this object successfully | ||
| 168 | + $this->parent = null; | ||
| 169 | + | ||
| 170 | + // Close down the php://temp file | ||
| 171 | + $this->__destruct(); | ||
| 172 | + } | ||
| 173 | + | ||
| 174 | + /** | ||
| 175 | + * Initialise this new cell collection | ||
| 176 | + * | ||
| 177 | + * @param PHPExcel_Worksheet $parent The worksheet for this cell collection | ||
| 178 | + * @param array of mixed $arguments Additional initialisation arguments | ||
| 179 | + */ | ||
| 180 | + public function __construct(PHPExcel_Worksheet $parent, $arguments) | ||
| 181 | + { | ||
| 182 | + $this->memoryCacheSize = (isset($arguments['memoryCacheSize'])) ? $arguments['memoryCacheSize'] : '1MB'; | ||
| 183 | + | ||
| 184 | + parent::__construct($parent); | ||
| 185 | + if (is_null($this->fileHandle)) { | ||
| 186 | + $this->fileHandle = fopen('php://temp/maxmemory:' . $this->memoryCacheSize, 'a+'); | ||
| 187 | + } | ||
| 188 | + } | ||
| 189 | + | ||
| 190 | + /** | ||
| 191 | + * Destroy this cell collection | ||
| 192 | + */ | ||
| 193 | + public function __destruct() | ||
| 194 | + { | ||
| 195 | + if (!is_null($this->fileHandle)) { | ||
| 196 | + fclose($this->fileHandle); | ||
| 197 | + } | ||
| 198 | + $this->fileHandle = null; | ||
| 199 | + } | ||
| 200 | +} |
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +/** | ||
| 4 | + * PHPExcel_CachedObjectStorage_SQLite | ||
| 5 | + * | ||
| 6 | + * Copyright (c) 2006 - 2015 PHPExcel | ||
| 7 | + * | ||
| 8 | + * This library is free software; you can redistribute it and/or | ||
| 9 | + * modify it under the terms of the GNU Lesser General Public | ||
| 10 | + * License as published by the Free Software Foundation; either | ||
| 11 | + * version 2.1 of the License, or (at your option) any later version. | ||
| 12 | + * | ||
| 13 | + * This library is distributed in the hope that it will be useful, | ||
| 14 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 16 | + * Lesser General Public License for more details. | ||
| 17 | + * | ||
| 18 | + * You should have received a copy of the GNU Lesser General Public | ||
| 19 | + * License along with this library; if not, write to the Free Software | ||
| 20 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 21 | + * | ||
| 22 | + * @category PHPExcel | ||
| 23 | + * @package PHPExcel_CachedObjectStorage | ||
| 24 | + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) | ||
| 25 | + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL | ||
| 26 | + * @version ##VERSION##, ##DATE## | ||
| 27 | + */ | ||
| 28 | +class PHPExcel_CachedObjectStorage_SQLite extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache | ||
| 29 | +{ | ||
| 30 | + /** | ||
| 31 | + * Database table name | ||
| 32 | + * | ||
| 33 | + * @var string | ||
| 34 | + */ | ||
| 35 | + private $TableName = null; | ||
| 36 | + | ||
| 37 | + /** | ||
| 38 | + * Database handle | ||
| 39 | + * | ||
| 40 | + * @var resource | ||
| 41 | + */ | ||
| 42 | + private $DBHandle = null; | ||
| 43 | + | ||
| 44 | + /** | ||
| 45 | + * Store cell data in cache for the current cell object if it's "dirty", | ||
| 46 | + * and the 'nullify' the current cell object | ||
| 47 | + * | ||
| 48 | + * @return void | ||
| 49 | + * @throws PHPExcel_Exception | ||
| 50 | + */ | ||
| 51 | + protected function storeData() | ||
| 52 | + { | ||
| 53 | + if ($this->currentCellIsDirty && !empty($this->currentObjectID)) { | ||
| 54 | + $this->currentObject->detach(); | ||
| 55 | + | ||
| 56 | + if (!$this->DBHandle->queryExec("INSERT OR REPLACE INTO kvp_".$this->TableName." VALUES('".$this->currentObjectID."','".sqlite_escape_string(serialize($this->currentObject))."')")) { | ||
| 57 | + throw new PHPExcel_Exception(sqlite_error_string($this->DBHandle->lastError())); | ||
| 58 | + } | ||
| 59 | + $this->currentCellIsDirty = false; | ||
| 60 | + } | ||
| 61 | + $this->currentObjectID = $this->currentObject = null; | ||
| 62 | + } | ||
| 63 | + | ||
| 64 | + /** | ||
| 65 | + * Add or Update a cell in cache identified by coordinate address | ||
| 66 | + * | ||
| 67 | + * @param string $pCoord Coordinate address of the cell to update | ||
| 68 | + * @param PHPExcel_Cell $cell Cell to update | ||
| 69 | + * @return PHPExcel_Cell | ||
| 70 | + * @throws PHPExcel_Exception | ||
| 71 | + */ | ||
| 72 | + public function addCacheData($pCoord, PHPExcel_Cell $cell) | ||
| 73 | + { | ||
| 74 | + if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) { | ||
| 75 | + $this->storeData(); | ||
| 76 | + } | ||
| 77 | + | ||
| 78 | + $this->currentObjectID = $pCoord; | ||
| 79 | + $this->currentObject = $cell; | ||
| 80 | + $this->currentCellIsDirty = true; | ||
| 81 | + | ||
| 82 | + return $cell; | ||
| 83 | + } | ||
| 84 | + | ||
| 85 | + /** | ||
| 86 | + * Get cell at a specific coordinate | ||
| 87 | + * | ||
| 88 | + * @param string $pCoord Coordinate of the cell | ||
| 89 | + * @throws PHPExcel_Exception | ||
| 90 | + * @return PHPExcel_Cell Cell that was found, or null if not found | ||
| 91 | + */ | ||
| 92 | + public function getCacheData($pCoord) | ||
| 93 | + { | ||
| 94 | + if ($pCoord === $this->currentObjectID) { | ||
| 95 | + return $this->currentObject; | ||
| 96 | + } | ||
| 97 | + $this->storeData(); | ||
| 98 | + | ||
| 99 | + $query = "SELECT value FROM kvp_".$this->TableName." WHERE id='".$pCoord."'"; | ||
| 100 | + $cellResultSet = $this->DBHandle->query($query, SQLITE_ASSOC); | ||
| 101 | + if ($cellResultSet === false) { | ||
| 102 | + throw new PHPExcel_Exception(sqlite_error_string($this->DBHandle->lastError())); | ||
| 103 | + } elseif ($cellResultSet->numRows() == 0) { | ||
| 104 | + // Return null if requested entry doesn't exist in cache | ||
| 105 | + return null; | ||
| 106 | + } | ||
| 107 | + | ||
| 108 | + // Set current entry to the requested entry | ||
| 109 | + $this->currentObjectID = $pCoord; | ||
| 110 | + | ||
| 111 | + $cellResult = $cellResultSet->fetchSingle(); | ||
| 112 | + $this->currentObject = unserialize($cellResult); | ||
| 113 | + // Re-attach this as the cell's parent | ||
| 114 | + $this->currentObject->attach($this); | ||
| 115 | + | ||
| 116 | + // Return requested entry | ||
| 117 | + return $this->currentObject; | ||
| 118 | + } | ||
| 119 | + | ||
| 120 | + /** | ||
| 121 | + * Is a value set for an indexed cell? | ||
| 122 | + * | ||
| 123 | + * @param string $pCoord Coordinate address of the cell to check | ||
| 124 | + * @return boolean | ||
| 125 | + */ | ||
| 126 | + public function isDataSet($pCoord) | ||
| 127 | + { | ||
| 128 | + if ($pCoord === $this->currentObjectID) { | ||
| 129 | + return true; | ||
| 130 | + } | ||
| 131 | + | ||
| 132 | + // Check if the requested entry exists in the cache | ||
| 133 | + $query = "SELECT id FROM kvp_".$this->TableName." WHERE id='".$pCoord."'"; | ||
| 134 | + $cellResultSet = $this->DBHandle->query($query, SQLITE_ASSOC); | ||
| 135 | + if ($cellResultSet === false) { | ||
| 136 | + throw new PHPExcel_Exception(sqlite_error_string($this->DBHandle->lastError())); | ||
| 137 | + } elseif ($cellResultSet->numRows() == 0) { | ||
| 138 | + // Return null if requested entry doesn't exist in cache | ||
| 139 | + return false; | ||
| 140 | + } | ||
| 141 | + return true; | ||
| 142 | + } | ||
| 143 | + | ||
| 144 | + /** | ||
| 145 | + * Delete a cell in cache identified by coordinate address | ||
| 146 | + * | ||
| 147 | + * @param string $pCoord Coordinate address of the cell to delete | ||
| 148 | + * @throws PHPExcel_Exception | ||
| 149 | + */ | ||
| 150 | + public function deleteCacheData($pCoord) | ||
| 151 | + { | ||
| 152 | + if ($pCoord === $this->currentObjectID) { | ||
| 153 | + $this->currentObject->detach(); | ||
| 154 | + $this->currentObjectID = $this->currentObject = null; | ||
| 155 | + } | ||
| 156 | + | ||
| 157 | + // Check if the requested entry exists in the cache | ||
| 158 | + $query = "DELETE FROM kvp_".$this->TableName." WHERE id='".$pCoord."'"; | ||
| 159 | + if (!$this->DBHandle->queryExec($query)) { | ||
| 160 | + throw new PHPExcel_Exception(sqlite_error_string($this->DBHandle->lastError())); | ||
| 161 | + } | ||
| 162 | + | ||
| 163 | + $this->currentCellIsDirty = false; | ||
| 164 | + } | ||
| 165 | + | ||
| 166 | + /** | ||
| 167 | + * Move a cell object from one address to another | ||
| 168 | + * | ||
| 169 | + * @param string $fromAddress Current address of the cell to move | ||
| 170 | + * @param string $toAddress Destination address of the cell to move | ||
| 171 | + * @return boolean | ||
| 172 | + */ | ||
| 173 | + public function moveCell($fromAddress, $toAddress) | ||
| 174 | + { | ||
| 175 | + if ($fromAddress === $this->currentObjectID) { | ||
| 176 | + $this->currentObjectID = $toAddress; | ||
| 177 | + } | ||
| 178 | + | ||
| 179 | + $query = "DELETE FROM kvp_".$this->TableName." WHERE id='".$toAddress."'"; | ||
| 180 | + $result = $this->DBHandle->exec($query); | ||
| 181 | + if ($result === false) { | ||
| 182 | + throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg()); | ||
| 183 | + } | ||
| 184 | + | ||
| 185 | + $query = "UPDATE kvp_".$this->TableName." SET id='".$toAddress."' WHERE id='".$fromAddress."'"; | ||
| 186 | + $result = $this->DBHandle->exec($query); | ||
| 187 | + if ($result === false) { | ||
| 188 | + throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg()); | ||
| 189 | + } | ||
| 190 | + | ||
| 191 | + return true; | ||
| 192 | + } | ||
| 193 | + | ||
| 194 | + /** | ||
| 195 | + * Get a list of all cell addresses currently held in cache | ||
| 196 | + * | ||
| 197 | + * @return string[] | ||
| 198 | + */ | ||
| 199 | + public function getCellList() | ||
| 200 | + { | ||
| 201 | + if ($this->currentObjectID !== null) { | ||
| 202 | + $this->storeData(); | ||
| 203 | + } | ||
| 204 | + | ||
| 205 | + $query = "SELECT id FROM kvp_".$this->TableName; | ||
| 206 | + $cellIdsResult = $this->DBHandle->unbufferedQuery($query, SQLITE_ASSOC); | ||
| 207 | + if ($cellIdsResult === false) { | ||
| 208 | + throw new PHPExcel_Exception(sqlite_error_string($this->DBHandle->lastError())); | ||
| 209 | + } | ||
| 210 | + | ||
| 211 | + $cellKeys = array(); | ||
| 212 | + foreach ($cellIdsResult as $row) { | ||
| 213 | + $cellKeys[] = $row['id']; | ||
| 214 | + } | ||
| 215 | + | ||
| 216 | + return $cellKeys; | ||
| 217 | + } | ||
| 218 | + | ||
| 219 | + /** | ||
| 220 | + * Clone the cell collection | ||
| 221 | + * | ||
| 222 | + * @param PHPExcel_Worksheet $parent The new worksheet | ||
| 223 | + * @return void | ||
| 224 | + */ | ||
| 225 | + public function copyCellCollection(PHPExcel_Worksheet $parent) | ||
| 226 | + { | ||
| 227 | + $this->currentCellIsDirty; | ||
| 228 | + $this->storeData(); | ||
| 229 | + | ||
| 230 | + // Get a new id for the new table name | ||
| 231 | + $tableName = str_replace('.', '_', $this->getUniqueID()); | ||
| 232 | + if (!$this->DBHandle->queryExec('CREATE TABLE kvp_'.$tableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB) | ||
| 233 | + AS SELECT * FROM kvp_'.$this->TableName) | ||
| 234 | + ) { | ||
| 235 | + throw new PHPExcel_Exception(sqlite_error_string($this->DBHandle->lastError())); | ||
| 236 | + } | ||
| 237 | + | ||
| 238 | + // Copy the existing cell cache file | ||
| 239 | + $this->TableName = $tableName; | ||
| 240 | + } | ||
| 241 | + | ||
| 242 | + /** | ||
| 243 | + * Clear the cell collection and disconnect from our parent | ||
| 244 | + * | ||
| 245 | + * @return void | ||
| 246 | + */ | ||
| 247 | + public function unsetWorksheetCells() | ||
| 248 | + { | ||
| 249 | + if (!is_null($this->currentObject)) { | ||
| 250 | + $this->currentObject->detach(); | ||
| 251 | + $this->currentObject = $this->currentObjectID = null; | ||
| 252 | + } | ||
| 253 | + // detach ourself from the worksheet, so that it can then delete this object successfully | ||
| 254 | + $this->parent = null; | ||
| 255 | + | ||
| 256 | + // Close down the temporary cache file | ||
| 257 | + $this->__destruct(); | ||
| 258 | + } | ||
| 259 | + | ||
| 260 | + /** | ||
| 261 | + * Initialise this new cell collection | ||
| 262 | + * | ||
| 263 | + * @param PHPExcel_Worksheet $parent The worksheet for this cell collection | ||
| 264 | + */ | ||
| 265 | + public function __construct(PHPExcel_Worksheet $parent) | ||
| 266 | + { | ||
| 267 | + parent::__construct($parent); | ||
| 268 | + if (is_null($this->DBHandle)) { | ||
| 269 | + $this->TableName = str_replace('.', '_', $this->getUniqueID()); | ||
| 270 | + $_DBName = ':memory:'; | ||
| 271 | + | ||
| 272 | + $this->DBHandle = new SQLiteDatabase($_DBName); | ||
| 273 | + if ($this->DBHandle === false) { | ||
| 274 | + throw new PHPExcel_Exception(sqlite_error_string($this->DBHandle->lastError())); | ||
| 275 | + } | ||
| 276 | + if (!$this->DBHandle->queryExec('CREATE TABLE kvp_'.$this->TableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB)')) { | ||
| 277 | + throw new PHPExcel_Exception(sqlite_error_string($this->DBHandle->lastError())); | ||
| 278 | + } | ||
| 279 | + } | ||
| 280 | + } | ||
| 281 | + | ||
| 282 | + /** | ||
| 283 | + * Destroy this cell collection | ||
| 284 | + */ | ||
| 285 | + public function __destruct() | ||
| 286 | + { | ||
| 287 | + if (!is_null($this->DBHandle)) { | ||
| 288 | + $this->DBHandle->queryExec('DROP TABLE kvp_'.$this->TableName); | ||
| 289 | + } | ||
| 290 | + $this->DBHandle = null; | ||
| 291 | + } | ||
| 292 | + | ||
| 293 | + /** | ||
| 294 | + * Identify whether the caching method is currently available | ||
| 295 | + * Some methods are dependent on the availability of certain extensions being enabled in the PHP build | ||
| 296 | + * | ||
| 297 | + * @return boolean | ||
| 298 | + */ | ||
| 299 | + public static function cacheMethodIsAvailable() | ||
| 300 | + { | ||
| 301 | + if (!function_exists('sqlite_open')) { | ||
| 302 | + return false; | ||
| 303 | + } | ||
| 304 | + | ||
| 305 | + return true; | ||
| 306 | + } | ||
| 307 | +} |
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +/** | ||
| 4 | + * PHPExcel_CachedObjectStorage_SQLite3 | ||
| 5 | + * | ||
| 6 | + * Copyright (c) 2006 - 2015 PHPExcel | ||
| 7 | + * | ||
| 8 | + * This library is free software; you can redistribute it and/or | ||
| 9 | + * modify it under the terms of the GNU Lesser General Public | ||
| 10 | + * License as published by the Free Software Foundation; either | ||
| 11 | + * version 2.1 of the License, or (at your option) any later version. | ||
| 12 | + * | ||
| 13 | + * This library is distributed in the hope that it will be useful, | ||
| 14 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 16 | + * Lesser General Public License for more details. | ||
| 17 | + * | ||
| 18 | + * You should have received a copy of the GNU Lesser General Public | ||
| 19 | + * License along with this library; if not, write to the Free Software | ||
| 20 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 21 | + * | ||
| 22 | + * @category PHPExcel | ||
| 23 | + * @package PHPExcel_CachedObjectStorage | ||
| 24 | + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) | ||
| 25 | + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL | ||
| 26 | + * @version ##VERSION##, ##DATE## | ||
| 27 | + */ | ||
| 28 | +class PHPExcel_CachedObjectStorage_SQLite3 extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache | ||
| 29 | +{ | ||
| 30 | + /** | ||
| 31 | + * Database table name | ||
| 32 | + * | ||
| 33 | + * @var string | ||
| 34 | + */ | ||
| 35 | + private $TableName = null; | ||
| 36 | + | ||
| 37 | + /** | ||
| 38 | + * Database handle | ||
| 39 | + * | ||
| 40 | + * @var resource | ||
| 41 | + */ | ||
| 42 | + private $DBHandle = null; | ||
| 43 | + | ||
| 44 | + /** | ||
| 45 | + * Prepared statement for a SQLite3 select query | ||
| 46 | + * | ||
| 47 | + * @var SQLite3Stmt | ||
| 48 | + */ | ||
| 49 | + private $selectQuery; | ||
| 50 | + | ||
| 51 | + /** | ||
| 52 | + * Prepared statement for a SQLite3 insert query | ||
| 53 | + * | ||
| 54 | + * @var SQLite3Stmt | ||
| 55 | + */ | ||
| 56 | + private $insertQuery; | ||
| 57 | + | ||
| 58 | + /** | ||
| 59 | + * Prepared statement for a SQLite3 update query | ||
| 60 | + * | ||
| 61 | + * @var SQLite3Stmt | ||
| 62 | + */ | ||
| 63 | + private $updateQuery; | ||
| 64 | + | ||
| 65 | + /** | ||
| 66 | + * Prepared statement for a SQLite3 delete query | ||
| 67 | + * | ||
| 68 | + * @var SQLite3Stmt | ||
| 69 | + */ | ||
| 70 | + private $deleteQuery; | ||
| 71 | + | ||
| 72 | + /** | ||
| 73 | + * Store cell data in cache for the current cell object if it's "dirty", | ||
| 74 | + * and the 'nullify' the current cell object | ||
| 75 | + * | ||
| 76 | + * @return void | ||
| 77 | + * @throws PHPExcel_Exception | ||
| 78 | + */ | ||
| 79 | + protected function storeData() | ||
| 80 | + { | ||
| 81 | + if ($this->currentCellIsDirty && !empty($this->currentObjectID)) { | ||
| 82 | + $this->currentObject->detach(); | ||
| 83 | + | ||
| 84 | + $this->insertQuery->bindValue('id', $this->currentObjectID, SQLITE3_TEXT); | ||
| 85 | + $this->insertQuery->bindValue('data', serialize($this->currentObject), SQLITE3_BLOB); | ||
| 86 | + $result = $this->insertQuery->execute(); | ||
| 87 | + if ($result === false) { | ||
| 88 | + throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg()); | ||
| 89 | + } | ||
| 90 | + $this->currentCellIsDirty = false; | ||
| 91 | + } | ||
| 92 | + $this->currentObjectID = $this->currentObject = null; | ||
| 93 | + } | ||
| 94 | + | ||
| 95 | + /** | ||
| 96 | + * Add or Update a cell in cache identified by coordinate address | ||
| 97 | + * | ||
| 98 | + * @param string $pCoord Coordinate address of the cell to update | ||
| 99 | + * @param PHPExcel_Cell $cell Cell to update | ||
| 100 | + * @return PHPExcel_Cell | ||
| 101 | + * @throws PHPExcel_Exception | ||
| 102 | + */ | ||
| 103 | + public function addCacheData($pCoord, PHPExcel_Cell $cell) | ||
| 104 | + { | ||
| 105 | + if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) { | ||
| 106 | + $this->storeData(); | ||
| 107 | + } | ||
| 108 | + | ||
| 109 | + $this->currentObjectID = $pCoord; | ||
| 110 | + $this->currentObject = $cell; | ||
| 111 | + $this->currentCellIsDirty = true; | ||
| 112 | + | ||
| 113 | + return $cell; | ||
| 114 | + } | ||
| 115 | + | ||
| 116 | + /** | ||
| 117 | + * Get cell at a specific coordinate | ||
| 118 | + * | ||
| 119 | + * @param string $pCoord Coordinate of the cell | ||
| 120 | + * @throws PHPExcel_Exception | ||
| 121 | + * @return PHPExcel_Cell Cell that was found, or null if not found | ||
| 122 | + */ | ||
| 123 | + public function getCacheData($pCoord) | ||
| 124 | + { | ||
| 125 | + if ($pCoord === $this->currentObjectID) { | ||
| 126 | + return $this->currentObject; | ||
| 127 | + } | ||
| 128 | + $this->storeData(); | ||
| 129 | + | ||
| 130 | + $this->selectQuery->bindValue('id', $pCoord, SQLITE3_TEXT); | ||
| 131 | + $cellResult = $this->selectQuery->execute(); | ||
| 132 | + if ($cellResult === false) { | ||
| 133 | + throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg()); | ||
| 134 | + } | ||
| 135 | + $cellData = $cellResult->fetchArray(SQLITE3_ASSOC); | ||
| 136 | + if ($cellData === false) { | ||
| 137 | + // Return null if requested entry doesn't exist in cache | ||
| 138 | + return null; | ||
| 139 | + } | ||
| 140 | + | ||
| 141 | + // Set current entry to the requested entry | ||
| 142 | + $this->currentObjectID = $pCoord; | ||
| 143 | + | ||
| 144 | + $this->currentObject = unserialize($cellData['value']); | ||
| 145 | + // Re-attach this as the cell's parent | ||
| 146 | + $this->currentObject->attach($this); | ||
| 147 | + | ||
| 148 | + // Return requested entry | ||
| 149 | + return $this->currentObject; | ||
| 150 | + } | ||
| 151 | + | ||
| 152 | + /** | ||
| 153 | + * Is a value set for an indexed cell? | ||
| 154 | + * | ||
| 155 | + * @param string $pCoord Coordinate address of the cell to check | ||
| 156 | + * @return boolean | ||
| 157 | + */ | ||
| 158 | + public function isDataSet($pCoord) | ||
| 159 | + { | ||
| 160 | + if ($pCoord === $this->currentObjectID) { | ||
| 161 | + return true; | ||
| 162 | + } | ||
| 163 | + | ||
| 164 | + // Check if the requested entry exists in the cache | ||
| 165 | + $this->selectQuery->bindValue('id', $pCoord, SQLITE3_TEXT); | ||
| 166 | + $cellResult = $this->selectQuery->execute(); | ||
| 167 | + if ($cellResult === false) { | ||
| 168 | + throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg()); | ||
| 169 | + } | ||
| 170 | + $cellData = $cellResult->fetchArray(SQLITE3_ASSOC); | ||
| 171 | + | ||
| 172 | + return ($cellData === false) ? false : true; | ||
| 173 | + } | ||
| 174 | + | ||
| 175 | + /** | ||
| 176 | + * Delete a cell in cache identified by coordinate address | ||
| 177 | + * | ||
| 178 | + * @param string $pCoord Coordinate address of the cell to delete | ||
| 179 | + * @throws PHPExcel_Exception | ||
| 180 | + */ | ||
| 181 | + public function deleteCacheData($pCoord) | ||
| 182 | + { | ||
| 183 | + if ($pCoord === $this->currentObjectID) { | ||
| 184 | + $this->currentObject->detach(); | ||
| 185 | + $this->currentObjectID = $this->currentObject = null; | ||
| 186 | + } | ||
| 187 | + | ||
| 188 | + // Check if the requested entry exists in the cache | ||
| 189 | + $this->deleteQuery->bindValue('id', $pCoord, SQLITE3_TEXT); | ||
| 190 | + $result = $this->deleteQuery->execute(); | ||
| 191 | + if ($result === false) { | ||
| 192 | + throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg()); | ||
| 193 | + } | ||
| 194 | + | ||
| 195 | + $this->currentCellIsDirty = false; | ||
| 196 | + } | ||
| 197 | + | ||
| 198 | + /** | ||
| 199 | + * Move a cell object from one address to another | ||
| 200 | + * | ||
| 201 | + * @param string $fromAddress Current address of the cell to move | ||
| 202 | + * @param string $toAddress Destination address of the cell to move | ||
| 203 | + * @return boolean | ||
| 204 | + */ | ||
| 205 | + public function moveCell($fromAddress, $toAddress) | ||
| 206 | + { | ||
| 207 | + if ($fromAddress === $this->currentObjectID) { | ||
| 208 | + $this->currentObjectID = $toAddress; | ||
| 209 | + } | ||
| 210 | + | ||
| 211 | + $this->deleteQuery->bindValue('id', $toAddress, SQLITE3_TEXT); | ||
| 212 | + $result = $this->deleteQuery->execute(); | ||
| 213 | + if ($result === false) { | ||
| 214 | + throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg()); | ||
| 215 | + } | ||
| 216 | + | ||
| 217 | + $this->updateQuery->bindValue('toid', $toAddress, SQLITE3_TEXT); | ||
| 218 | + $this->updateQuery->bindValue('fromid', $fromAddress, SQLITE3_TEXT); | ||
| 219 | + $result = $this->updateQuery->execute(); | ||
| 220 | + if ($result === false) { | ||
| 221 | + throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg()); | ||
| 222 | + } | ||
| 223 | + | ||
| 224 | + return true; | ||
| 225 | + } | ||
| 226 | + | ||
| 227 | + /** | ||
| 228 | + * Get a list of all cell addresses currently held in cache | ||
| 229 | + * | ||
| 230 | + * @return string[] | ||
| 231 | + */ | ||
| 232 | + public function getCellList() | ||
| 233 | + { | ||
| 234 | + if ($this->currentObjectID !== null) { | ||
| 235 | + $this->storeData(); | ||
| 236 | + } | ||
| 237 | + | ||
| 238 | + $query = "SELECT id FROM kvp_".$this->TableName; | ||
| 239 | + $cellIdsResult = $this->DBHandle->query($query); | ||
| 240 | + if ($cellIdsResult === false) { | ||
| 241 | + throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg()); | ||
| 242 | + } | ||
| 243 | + | ||
| 244 | + $cellKeys = array(); | ||
| 245 | + while ($row = $cellIdsResult->fetchArray(SQLITE3_ASSOC)) { | ||
| 246 | + $cellKeys[] = $row['id']; | ||
| 247 | + } | ||
| 248 | + | ||
| 249 | + return $cellKeys; | ||
| 250 | + } | ||
| 251 | + | ||
| 252 | + /** | ||
| 253 | + * Clone the cell collection | ||
| 254 | + * | ||
| 255 | + * @param PHPExcel_Worksheet $parent The new worksheet | ||
| 256 | + * @return void | ||
| 257 | + */ | ||
| 258 | + public function copyCellCollection(PHPExcel_Worksheet $parent) | ||
| 259 | + { | ||
| 260 | + $this->currentCellIsDirty; | ||
| 261 | + $this->storeData(); | ||
| 262 | + | ||
| 263 | + // Get a new id for the new table name | ||
| 264 | + $tableName = str_replace('.', '_', $this->getUniqueID()); | ||
| 265 | + if (!$this->DBHandle->exec('CREATE TABLE kvp_'.$tableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB) | ||
| 266 | + AS SELECT * FROM kvp_'.$this->TableName) | ||
| 267 | + ) { | ||
| 268 | + throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg()); | ||
| 269 | + } | ||
| 270 | + | ||
| 271 | + // Copy the existing cell cache file | ||
| 272 | + $this->TableName = $tableName; | ||
| 273 | + } | ||
| 274 | + | ||
| 275 | + /** | ||
| 276 | + * Clear the cell collection and disconnect from our parent | ||
| 277 | + * | ||
| 278 | + * @return void | ||
| 279 | + */ | ||
| 280 | + public function unsetWorksheetCells() | ||
| 281 | + { | ||
| 282 | + if (!is_null($this->currentObject)) { | ||
| 283 | + $this->currentObject->detach(); | ||
| 284 | + $this->currentObject = $this->currentObjectID = null; | ||
| 285 | + } | ||
| 286 | + // detach ourself from the worksheet, so that it can then delete this object successfully | ||
| 287 | + $this->parent = null; | ||
| 288 | + | ||
| 289 | + // Close down the temporary cache file | ||
| 290 | + $this->__destruct(); | ||
| 291 | + } | ||
| 292 | + | ||
| 293 | + /** | ||
| 294 | + * Initialise this new cell collection | ||
| 295 | + * | ||
| 296 | + * @param PHPExcel_Worksheet $parent The worksheet for this cell collection | ||
| 297 | + */ | ||
| 298 | + public function __construct(PHPExcel_Worksheet $parent) | ||
| 299 | + { | ||
| 300 | + parent::__construct($parent); | ||
| 301 | + if (is_null($this->DBHandle)) { | ||
| 302 | + $this->TableName = str_replace('.', '_', $this->getUniqueID()); | ||
| 303 | + $_DBName = ':memory:'; | ||
| 304 | + | ||
| 305 | + $this->DBHandle = new SQLite3($_DBName); | ||
| 306 | + if ($this->DBHandle === false) { | ||
| 307 | + throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg()); | ||
| 308 | + } | ||
| 309 | + if (!$this->DBHandle->exec('CREATE TABLE kvp_'.$this->TableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB)')) { | ||
| 310 | + throw new PHPExcel_Exception($this->DBHandle->lastErrorMsg()); | ||
| 311 | + } | ||
| 312 | + } | ||
| 313 | + | ||
| 314 | + $this->selectQuery = $this->DBHandle->prepare("SELECT value FROM kvp_".$this->TableName." WHERE id = :id"); | ||
| 315 | + $this->insertQuery = $this->DBHandle->prepare("INSERT OR REPLACE INTO kvp_".$this->TableName." VALUES(:id,:data)"); | ||
| 316 | + $this->updateQuery = $this->DBHandle->prepare("UPDATE kvp_".$this->TableName." SET id=:toId WHERE id=:fromId"); | ||
| 317 | + $this->deleteQuery = $this->DBHandle->prepare("DELETE FROM kvp_".$this->TableName." WHERE id = :id"); | ||
| 318 | + } | ||
| 319 | + | ||
| 320 | + /** | ||
| 321 | + * Destroy this cell collection | ||
| 322 | + */ | ||
| 323 | + public function __destruct() | ||
| 324 | + { | ||
| 325 | + if (!is_null($this->DBHandle)) { | ||
| 326 | + $this->DBHandle->exec('DROP TABLE kvp_'.$this->TableName); | ||
| 327 | + $this->DBHandle->close(); | ||
| 328 | + } | ||
| 329 | + $this->DBHandle = null; | ||
| 330 | + } | ||
| 331 | + | ||
| 332 | + /** | ||
| 333 | + * Identify whether the caching method is currently available | ||
| 334 | + * Some methods are dependent on the availability of certain extensions being enabled in the PHP build | ||
| 335 | + * | ||
| 336 | + * @return boolean | ||
| 337 | + */ | ||
| 338 | + public static function cacheMethodIsAvailable() | ||
| 339 | + { | ||
| 340 | + if (!class_exists('SQLite3', false)) { | ||
| 341 | + return false; | ||
| 342 | + } | ||
| 343 | + | ||
| 344 | + return true; | ||
| 345 | + } | ||
| 346 | +} |
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +/** | ||
| 4 | + * PHPExcel_CachedObjectStorage_Wincache | ||
| 5 | + * | ||
| 6 | + * Copyright (c) 2006 - 2015 PHPExcel | ||
| 7 | + * | ||
| 8 | + * This library is free software; you can redistribute it and/or | ||
| 9 | + * modify it under the terms of the GNU Lesser General Public | ||
| 10 | + * License as published by the Free Software Foundation; either | ||
| 11 | + * version 2.1 of the License, or (at your option) any later version. | ||
| 12 | + * | ||
| 13 | + * This library is distributed in the hope that it will be useful, | ||
| 14 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 16 | + * Lesser General Public License for more details. | ||
| 17 | + * | ||
| 18 | + * You should have received a copy of the GNU Lesser General Public | ||
| 19 | + * License along with this library; if not, write to the Free Software | ||
| 20 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 21 | + * | ||
| 22 | + * @category PHPExcel | ||
| 23 | + * @package PHPExcel_CachedObjectStorage | ||
| 24 | + * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) | ||
| 25 | + * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL | ||
| 26 | + * @version ##VERSION##, ##DATE## | ||
| 27 | + */ | ||
| 28 | +class PHPExcel_CachedObjectStorage_Wincache extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache | ||
| 29 | +{ | ||
| 30 | + /** | ||
| 31 | + * Prefix used to uniquely identify cache data for this worksheet | ||
| 32 | + * | ||
| 33 | + * @var string | ||
| 34 | + */ | ||
| 35 | + private $cachePrefix = null; | ||
| 36 | + | ||
| 37 | + /** | ||
| 38 | + * Cache timeout | ||
| 39 | + * | ||
| 40 | + * @var integer | ||
| 41 | + */ | ||
| 42 | + private $cacheTime = 600; | ||
| 43 | + | ||
| 44 | + | ||
| 45 | + /** | ||
| 46 | + * Store cell data in cache for the current cell object if it's "dirty", | ||
| 47 | + * and the 'nullify' the current cell object | ||
| 48 | + * | ||
| 49 | + * @return void | ||
| 50 | + * @throws PHPExcel_Exception | ||
| 51 | + */ | ||
| 52 | + protected function storeData() | ||
| 53 | + { | ||
| 54 | + if ($this->currentCellIsDirty && !empty($this->currentObjectID)) { | ||
| 55 | + $this->currentObject->detach(); | ||
| 56 | + | ||
| 57 | + $obj = serialize($this->currentObject); | ||
| 58 | + if (wincache_ucache_exists($this->cachePrefix.$this->currentObjectID.'.cache')) { | ||
| 59 | + if (!wincache_ucache_set($this->cachePrefix.$this->currentObjectID.'.cache', $obj, $this->cacheTime)) { | ||
| 60 | + $this->__destruct(); | ||
| 61 | + throw new PHPExcel_Exception('Failed to store cell '.$this->currentObjectID.' in WinCache'); | ||
| 62 | + } | ||
| 63 | + } else { | ||
| 64 | + if (!wincache_ucache_add($this->cachePrefix.$this->currentObjectID.'.cache', $obj, $this->cacheTime)) { | ||
| 65 | + $this->__destruct(); | ||
| 66 | + throw new PHPExcel_Exception('Failed to store cell '.$this->currentObjectID.' in WinCache'); | ||
| 67 | + } | ||
| 68 | + } | ||
| 69 | + $this->currentCellIsDirty = false; | ||
| 70 | + } | ||
| 71 | + | ||
| 72 | + $this->currentObjectID = $this->currentObject = null; | ||
| 73 | + } | ||
| 74 | + | ||
| 75 | + /** | ||
| 76 | + * Add or Update a cell in cache identified by coordinate address | ||
| 77 | + * | ||
| 78 | + * @param string $pCoord Coordinate address of the cell to update | ||
| 79 | + * @param PHPExcel_Cell $cell Cell to update | ||
| 80 | + * @return PHPExcel_Cell | ||
| 81 | + * @throws PHPExcel_Exception | ||
| 82 | + */ | ||
| 83 | + public function addCacheData($pCoord, PHPExcel_Cell $cell) | ||
| 84 | + { | ||
| 85 | + if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) { | ||
| 86 | + $this->storeData(); | ||
| 87 | + } | ||
| 88 | + $this->cellCache[$pCoord] = true; | ||
| 89 | + | ||
| 90 | + $this->currentObjectID = $pCoord; | ||
| 91 | + $this->currentObject = $cell; | ||
| 92 | + $this->currentCellIsDirty = true; | ||
| 93 | + | ||
| 94 | + return $cell; | ||
| 95 | + } | ||
| 96 | + | ||
| 97 | + /** | ||
| 98 | + * Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell? | ||
| 99 | + * | ||
| 100 | + * @param string $pCoord Coordinate address of the cell to check | ||
| 101 | + * @return boolean | ||
| 102 | + */ | ||
| 103 | + public function isDataSet($pCoord) | ||
| 104 | + { | ||
| 105 | + // Check if the requested entry is the current object, or exists in the cache | ||
| 106 | + if (parent::isDataSet($pCoord)) { | ||
| 107 | + if ($this->currentObjectID == $pCoord) { | ||
| 108 | + return true; | ||
| 109 | + } | ||
| 110 | + // Check if the requested entry still exists in cache | ||
| 111 | + $success = wincache_ucache_exists($this->cachePrefix.$pCoord.'.cache'); | ||
| 112 | + if ($success === false) { | ||
| 113 | + // Entry no longer exists in Wincache, so clear it from the cache array | ||
| 114 | + parent::deleteCacheData($pCoord); | ||
| 115 | + throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in WinCache'); | ||
| 116 | + } | ||
| 117 | + return true; | ||
| 118 | + } | ||
| 119 | + return false; | ||
| 120 | + } | ||
| 121 | + | ||
| 122 | + | ||
| 123 | + /** | ||
| 124 | + * Get cell at a specific coordinate | ||
| 125 | + * | ||
| 126 | + * @param string $pCoord Coordinate of the cell | ||
| 127 | + * @throws PHPExcel_Exception | ||
| 128 | + * @return PHPExcel_Cell Cell that was found, or null if not found | ||
| 129 | + */ | ||
| 130 | + public function getCacheData($pCoord) | ||
| 131 | + { | ||
| 132 | + if ($pCoord === $this->currentObjectID) { | ||
| 133 | + return $this->currentObject; | ||
| 134 | + } | ||
| 135 | + $this->storeData(); | ||
| 136 | + | ||
| 137 | + // Check if the entry that has been requested actually exists | ||
| 138 | + $obj = null; | ||
| 139 | + if (parent::isDataSet($pCoord)) { | ||
| 140 | + $success = false; | ||
| 141 | + $obj = wincache_ucache_get($this->cachePrefix.$pCoord.'.cache', $success); | ||
| 142 | + if ($success === false) { | ||
| 143 | + // Entry no longer exists in WinCache, so clear it from the cache array | ||
| 144 | + parent::deleteCacheData($pCoord); | ||
| 145 | + throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in WinCache'); | ||
| 146 | + } | ||
| 147 | + } else { | ||
| 148 | + // Return null if requested entry doesn't exist in cache | ||
| 149 | + return null; | ||
| 150 | + } | ||
| 151 | + | ||
| 152 | + // Set current entry to the requested entry | ||
| 153 | + $this->currentObjectID = $pCoord; | ||
| 154 | + $this->currentObject = unserialize($obj); | ||
| 155 | + // Re-attach this as the cell's parent | ||
| 156 | + $this->currentObject->attach($this); | ||
| 157 | + | ||
| 158 | + // Return requested entry | ||
| 159 | + return $this->currentObject; | ||
| 160 | + } | ||
| 161 | + | ||
| 162 | + | ||
| 163 | + /** | ||
| 164 | + * Get a list of all cell addresses currently held in cache | ||
| 165 | + * | ||
| 166 | + * @return string[] | ||
| 167 | + */ | ||
| 168 | + public function getCellList() | ||
| 169 | + { | ||
| 170 | + if ($this->currentObjectID !== null) { | ||
| 171 | + $this->storeData(); | ||
| 172 | + } | ||
| 173 | + | ||
| 174 | + return parent::getCellList(); | ||
| 175 | + } | ||
| 176 | + | ||
| 177 | + /** | ||
| 178 | + * Delete a cell in cache identified by coordinate address | ||
| 179 | + * | ||
| 180 | + * @param string $pCoord Coordinate address of the cell to delete | ||
| 181 | + * @throws PHPExcel_Exception | ||
| 182 | + */ | ||
| 183 | + public function deleteCacheData($pCoord) | ||
| 184 | + { | ||
| 185 | + // Delete the entry from Wincache | ||
| 186 | + wincache_ucache_delete($this->cachePrefix.$pCoord.'.cache'); | ||
| 187 | + | ||
| 188 | + // Delete the entry from our cell address array | ||
| 189 | + parent::deleteCacheData($pCoord); | ||
| 190 | + } | ||
| 191 | + | ||
| 192 | + /** | ||
| 193 | + * Clone the cell collection | ||
| 194 | + * | ||
| 195 | + * @param PHPExcel_Worksheet $parent The new worksheet | ||
| 196 | + * @return void | ||
| 197 | + */ | ||
| 198 | + public function copyCellCollection(PHPExcel_Worksheet $parent) | ||
| 199 | + { | ||
| 200 | + parent::copyCellCollection($parent); | ||
| 201 | + // Get a new id for the new file name | ||
| 202 | + $baseUnique = $this->getUniqueID(); | ||
| 203 | + $newCachePrefix = substr(md5($baseUnique), 0, 8) . '.'; | ||
| 204 | + $cacheList = $this->getCellList(); | ||
| 205 | + foreach ($cacheList as $cellID) { | ||
| 206 | + if ($cellID != $this->currentObjectID) { | ||
| 207 | + $success = false; | ||
| 208 | + $obj = wincache_ucache_get($this->cachePrefix.$cellID.'.cache', $success); | ||
| 209 | + if ($success === false) { | ||
| 210 | + // Entry no longer exists in WinCache, so clear it from the cache array | ||
| 211 | + parent::deleteCacheData($cellID); | ||
| 212 | + throw new PHPExcel_Exception('Cell entry '.$cellID.' no longer exists in Wincache'); | ||
| 213 | + } | ||
| 214 | + if (!wincache_ucache_add($newCachePrefix.$cellID.'.cache', $obj, $this->cacheTime)) { | ||
| 215 | + $this->__destruct(); | ||
| 216 | + throw new PHPExcel_Exception('Failed to store cell '.$cellID.' in Wincache'); | ||
| 217 | + } | ||
| 218 | + } | ||
| 219 | + } | ||
| 220 | + $this->cachePrefix = $newCachePrefix; | ||
| 221 | + } | ||
| 222 | + | ||
| 223 | + | ||
| 224 | + /** | ||
| 225 | + * Clear the cell collection and disconnect from our parent | ||
| 226 | + * | ||
| 227 | + * @return void | ||
| 228 | + */ | ||
| 229 | + public function unsetWorksheetCells() | ||
| 230 | + { | ||
| 231 | + if (!is_null($this->currentObject)) { | ||
| 232 | + $this->currentObject->detach(); | ||
| 233 | + $this->currentObject = $this->currentObjectID = null; | ||
| 234 | + } | ||
| 235 | + | ||
| 236 | + // Flush the WinCache cache | ||
| 237 | + $this->__destruct(); | ||
| 238 | + | ||
| 239 | + $this->cellCache = array(); | ||
| 240 | + | ||
| 241 | + // detach ourself from the worksheet, so that it can then delete this object successfully | ||
| 242 | + $this->parent = null; | ||
| 243 | + } | ||
| 244 | + | ||
| 245 | + /** | ||
| 246 | + * Initialise this new cell collection | ||
| 247 | + * | ||
| 248 | + * @param PHPExcel_Worksheet $parent The worksheet for this cell collection | ||
| 249 | + * @param array of mixed $arguments Additional initialisation arguments | ||
| 250 | + */ | ||
| 251 | + public function __construct(PHPExcel_Worksheet $parent, $arguments) | ||
| 252 | + { | ||
| 253 | + $cacheTime = (isset($arguments['cacheTime'])) ? $arguments['cacheTime'] : 600; | ||
| 254 | + | ||
| 255 | + if (is_null($this->cachePrefix)) { | ||
| 256 | + $baseUnique = $this->getUniqueID(); | ||
| 257 | + $this->cachePrefix = substr(md5($baseUnique), 0, 8).'.'; | ||
| 258 | + $this->cacheTime = $cacheTime; | ||
| 259 | + | ||
| 260 | + parent::__construct($parent); | ||
| 261 | + } | ||
| 262 | + } | ||
| 263 | + | ||
| 264 | + /** | ||
| 265 | + * Destroy this cell collection | ||
| 266 | + */ | ||
| 267 | + public function __destruct() | ||
| 268 | + { | ||
| 269 | + $cacheList = $this->getCellList(); | ||
| 270 | + foreach ($cacheList as $cellID) { | ||
| 271 | + wincache_ucache_delete($this->cachePrefix.$cellID.'.cache'); | ||
| 272 | + } | ||
| 273 | + } | ||
| 274 | + | ||
| 275 | + /** | ||
| 276 | + * Identify whether the caching method is currently available | ||
| 277 | + * Some methods are dependent on the availability of certain extensions being enabled in the PHP build | ||
| 278 | + * | ||
| 279 | + * @return boolean | ||
| 280 | + */ | ||
| 281 | + public static function cacheMethodIsAvailable() | ||
| 282 | + { | ||
| 283 | + if (!function_exists('wincache_ucache_add')) { | ||
| 284 | + return false; | ||
| 285 | + } | ||
| 286 | + | ||
| 287 | + return true; | ||
| 288 | + } | ||
| 289 | +} |
-
Please register or login to post a comment