Completed
Push — master ( c02c23...f37d2c )
by Reginaldo
28:44
created

ProdutoController::getUserActive()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 6

Duplication

Lines 11
Ratio 100 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
nc 1
nop 1
dl 11
loc 11
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
ini_set('max_execution_time', 300);
4
5
require_once(ROOT . DS . 'vendor' . DS . 'autoload.php');
6
7
use Dompdf\Dompdf;
8
9
10
class ProdutoController extends AppController{		
11
12
	public function listar_cadastros() {
13
		$this->layout = 'wadmin';
14
	}
15
16
	public function listar_cadastros_ajax() {
0 ignored issues
show
Coding Style introduced by
listar_cadastros_ajax uses the super-global variable $_GET which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
17
		$this->layout = 'ajax';
18
19
		$aColumns = array( 'sku', 'imagem', 'nome', 'preco', 'estoque' );
20
		
21
		$conditions = array('conditions' =>
22
			array(
23
				'ativo' => 1,
24
				'id_usuario' => $this->instancia
25
			)
26
		);
27
28
		$allProdutos = $this->Produto->find('all', $conditions);
29
		
30 View Code Duplication
		if ( isset( $_GET['iDisplayStart'] ) && $_GET['iDisplayLength'] != '-1' )
31
		{
32
			$conditions['offset'] = $_GET['iDisplayStart'];
33
			$conditions['limit'] = $_GET['iDisplayLength'];
34
		}
35
36 View Code Duplication
		if ( isset( $_GET['iSortCol_0'] ) )
37
		{
38
			for ( $i=0 ; $i < intval( $_GET['iSortingCols'] ) ; $i++ )
39
			{
40
				if ( $_GET[ 'bSortable_' . intval($_GET['iSortCol_' . $i]) ] == "true" )
41
				{
42
					$conditions['order'] = array('Produto.' . $aColumns[intval($_GET['iSortCol_' . $i])] => $_GET['sSortDir_'.$i]);
43
				}
44
			}
45
		}
46
47 View Code Duplication
		if ( isset( $_GET['sSearch'] ) && !empty( $_GET['sSearch'] ) )
48
		{
49
			$conditions['conditions']['Produto.nome LIKE '] = '%' . $_GET['sSearch'] . '%';
50
		}
51
		
52
		$produtos = $this->Produto->find('all', $conditions);
53
54
		$output = array(
55
			"sEcho" => intval($_GET['sEcho']),
56
			"iTotalDisplayRecords" => count($allProdutos),
57
			"iTotalRecords" => count($produtos),
58
			"aaData" => array()
59
		);
60
61 View Code Duplication
		foreach ( $produtos as $i => $produto )
62
		{
63
			$row = array();
64
65
			for ( $i=0 ; $i < count($aColumns) ; $i++ )
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
66
			{
67
				$value = $produto['Produto'][$aColumns[$i]];
68
69
				if ($aColumns[$i] == "imagem")
70
				{
71
					$value = '<img src="/uploads/produto/imagens/' . $produto['Produto'][$aColumns[$i]] . '" width="120" height="120">';
72
73
					if (!isset($produto['Produto'][$aColumns[$i]]) || empty($produto['Produto'][$aColumns[$i]]))
74
					{
75
						$value = '<img src="/images/no_image.png" width="120" height="120">';
76
					}
77
				}
78
				
79
				$row[] = $value;
80
			}
81
82
			$output['aaData'][] = $row;
83
		}
84
		
85
		echo json_encode($output);
86
		exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The method listar_cadastros_ajax() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
87
	}
88
89
	public function listar_cadastros_estoque_minimo(){
90
		$this->layout = 'wadmin';
91
	}
92
93
	public function listar_cadastros_estoque_minimo_ajax(){
0 ignored issues
show
Coding Style introduced by
listar_cadastros_estoque_minimo_ajax uses the super-global variable $_GET which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
94
95
		$this->layout = 'ajax';
96
97
		$aColumns = array( 'sku', 'imagem', 'nome', 'preco', 'estoque' );
98
99
		$this->loadModel('Usuario');
100
101
		$usuario = $this->Usuario->find('all', array('conditions' =>
102
				array(
103
					'Usuario.id' => $this->instancia
104
				)
105
			)
106
		)[0]['Usuario'];
107
		
108
		$conditions = array('conditions' =>
109
			array(
110
				'ativo' => 1,
111
				'id_usuario' => $this->instancia,
112
				'Produto.quantidade_minima <= ' => 'Produto.estoque',
113
				'Produto.estoque <= ' => $usuario['estoque_minimo']
114
			)
115
		);
116
117
		$allProdutos = $this->Produto->find('all', $conditions);
118
		
119 View Code Duplication
		if ( isset( $_GET['iDisplayStart'] ) && $_GET['iDisplayLength'] != '-1' )
120
		{
121
			$conditions['offset'] = $_GET['iDisplayStart'];
122
			$conditions['limit'] = $_GET['iDisplayLength'];
123
		}
124
125 View Code Duplication
		if ( isset( $_GET['iSortCol_0'] ) )
126
		{
127
			for ( $i=0 ; $i < intval( $_GET['iSortingCols'] ) ; $i++ )
128
			{
129
				if ( $_GET[ 'bSortable_' . intval($_GET['iSortCol_' . $i]) ] == "true" )
130
				{
131
					$conditions['order'] = array('Produto.' . $aColumns[intval($_GET['iSortCol_' . $i])] => $_GET['sSortDir_'.$i]);
132
				}
133
			}
134
		}
135
136 View Code Duplication
		if ( isset( $_GET['sSearch'] ) && !empty( $_GET['sSearch'] ) )
137
		{
138
			$conditions['conditions']['Produto.nome LIKE '] = '%' . $_GET['sSearch'] . '%';
139
		}
140
		
141
		$produtos = $this->Produto->find('all', $conditions);
142
143
		$output = array(
144
			"sEcho" => intval($_GET['sEcho']),
145
			"iTotalDisplayRecords" => count($allProdutos),
146
			"iTotalRecords" => count($produtos),
147
			"aaData" => array()
148
		);
149
150 View Code Duplication
		foreach ( $produtos as $i => $produto )
151
		{
152
			$row = array();
153
154
			for ( $i=0 ; $i < count($aColumns) ; $i++ )
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
155
			{
156
				$value = $produto['Produto'][$aColumns[$i]];
157
158
				if ($aColumns[$i] == "imagem")
159
				{
160
					$value = '<img src="/uploads/produto/imagens/' . $produto['Produto'][$aColumns[$i]] . '" width="120" height="120">';
161
162
					if (!isset($produto['Produto'][$aColumns[$i]]) || empty($produto['Produto'][$aColumns[$i]]))
163
					{
164
						$value = '<img src="/images/no_image.png" width="120" height="120">';
165
					}
166
				}
167
				
168
				$row[] = $value;
169
			}
170
171
			$output['aaData'][] = $row;
172
		}
173
		
174
		echo json_encode($output);
175
		exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The method listar_cadastros_estoque_minimo_ajax() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
176
	}
177
178
	public function baixar_estoque_minimo_pdf() {
179
		$this->loadModel('Produto');
180
		$this->loadModel('Usuario');
181
182
		$dompdf = new Dompdf();
183
184
		$usuario = $this->Usuario->find('all', array('conditions' =>
185
				array(
186
					'Usuario.id' => $this->instancia
187
				)
188
			)
189
		)[0]['Usuario'];
190
191
		$conditions = array('conditions' =>
192
			array(
193
				'ativo' => 1,
194
				'id_usuario' => $this->instancia,
195
				'Produto.quantidade_minima <= ' => 'Produto.estoque',
196
				'Produto.estoque <= ' => $usuario['estoque_minimo']
197
			)
198
		);
199
200
		$produtos = $this->Produto->find('all', $conditions);
201
202
		$html = $this->getProdutosEstoqueMinimoComoHtml($produtos);
203
204
		$dompdf->loadHtml($html);
205
206
		$dompdf->setPaper('A4');
207
208
		$dompdf->render();
209
210
		$dompdf->stream();
211
212
		exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The method baixar_estoque_minimo_pdf() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
213
	}
214
215
	public function getProdutosEstoqueMinimoComoHtml($produtos) {
216
    	ob_start();
217
218
		$html = '';
219
		$html .= '<html>';
220
		$html .= '<head>';
221
		$html .= '	<title></title>';
222
		$html .= '</head>';
223
		$html .= '<body>';
224
		$html .= '';
225
		$html .= '	<table style="background-color: #cacaca;"  width="100%" valign="center" align="center">';
226
		$html .= '		<tr align="center">';
227
		$html .= '			<td>';
228
		$html .= '				<h2>Produtos com quantidade de estoque minimo</h2>';
229
		$html .= '			</td>';
230
		$html .= '		</tr> ';
231
		$html .= '	</table>';
232
		$html .= '	<br>';
233
		$html .= '	<br>';
234
		$html .= '	<table  width="100%" valign="center" align="center">';
235
		$html .= '		<tr style="background-color: #cacaca;" align="center">';
236
		$html .= '			<td>';
237
		$html .= '				<h2>Produtos</h2>';
238
		$html .= '			</td>';
239
		$html .= '		</tr> ';
240
		$html .= '	</table>';
241
		$html .= '	<br>';
242
		$html .= '	<table  width="100%" valign="center" align="center">';
243
		$html .= '		<tr>';
244
		$html .= '			<td>';
245
		$html .= '				<table width="100%" valign="center" align="center">';
246
		$html .= '					<tr style="background-color: #cacaca;">';
247
		$html .= '						<td>Nome Produto</td>';
248
		$html .= '						<td>Quantidade</td>';
249
		$html .= '						<td>Custo</td>';
250
		$html .= '					</tr>';
251
		$html .= '';
252
253
		foreach ($produtos as $i => $produto) {
254
			if ($i > 30)
255
				break;
256
257
			$html .= '					<tr>';
258
			$html .= '						<td>' . $produto['Produto']['nome'] . '</td>';
259
			$html .= '						<td>' . $produto['Produto']['estoque'] . '</td>';
260
			$html .= '						<td>R$ ' . number_format($produto['Produto']['custo'], 2, ',', '.') . '</td>';
261
			$html .= '					</tr>';
262
		}
263
264
		$html .= '				</table>';
265
		$html .= '			</td>';
266
		$html .= '		</tr>';
267
		$html .= '	</table>';
268
		$html .= '	<br>';
269
		$html .= '';
270
		$html .= '</body>';
271
		$html .= '</html>';
272
273
		return $html;
274
	}
275
276 View Code Duplication
	public function adicionar_cadastro() {
277
		$this->loadModel('Categoria');
278
279
		$this->set('categorias', $this->Categoria->find('all', 
280
				array('conditions' => 
281
					array('ativo' => 1,
282
						  'usuario_id' => $this->instancia
283
					)
284
				)
285
			)
286
		);	
287
288
		$this->layout = 'wadmin';
289
	}
290
291
	public function s_adicionar_cadastro() {
0 ignored issues
show
Coding Style introduced by
s_adicionar_cadastro uses the super-global variable $_FILES which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
292
		$dados  = $this->request->data('dados');
293
294
		$variacoes = $this->request->data('variacao');
295
296
		$image  = $_FILES['imagem'];
297
298
		$retorno = $this->uploadImage($image);
299
300
		if (!$retorno['status']) 
301
			$this->Session->setFlash('Não foi possivel salvar a imagem tente novamente');
302
303
		$dados['imagem'] = $retorno['nome'];
304
		$dados['id_usuario'] = $this->instancia;
305
		$dados['ativo'] = 1;
306
		$dados['id_alias'] = $this->id_alias();
307
308
		if($this->Produto->save($dados)) {
309
			$produto_id = $this->Produto->getLastInsertId();
310
			
311
			require 'VariacaoController.php';
312
313
			$objVariacaoController = new VariacaoController();
314
315
			$objVariacaoController->s_adicionar_variacao($variacoes, $produto_id, $this->instancia);			
316
317
			$this->Session->setFlash('Produto salvo com sucesso!');
318
            
319
            return $this->redirect('/produto/listar_cadastros');
320
		} else {
321
			$this->Session->setFlash('Ocorreu um erro ao salva o produto!');
322
            
323
            return $this->redirect('/produto/listar_cadastros');
324
		}
325
	}
326
327
	public function editar_cadastro($id) {
328
		$this->layout = 'wadmin';
329
330
		$this->loadModel('Variacao');
331
332
		$query = array (
333
			'joins' => array(
334
				    array(
335
				        'table' => 'produtos',
336
				        'alias' => 'Produto',
337
				        'type' => 'LEFT',
338
				        'conditions' => array(
339
				            'Variacao.produto_id = Produto.id',
340
				        ),
341
				    )
342
				),
343
	        'conditions' => array('Variacao.produto_id' => $id, 'Variacao.ativo' => 1),
344
	        'fields' => array('Produto.id, Variacao.*'),
345
		);
346
347
		$variacoes = $this->set('variacoes', $this->Variacao->find('all', $query));
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $variacoes is correct as $this->set('variacoes', ...o->find('all', $query)) (which targets Controller::set()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
348
349
		$this->set('produto', $this->Produto->find('all', 
350
				array('conditions' => 
351
					array('ativo' => 1,
352
						  'id' => $id
353
					)
354
				)
355
			)[0]
356
		);
357
358
		$this->loadModel('Categoria');
359
360
		$this->set('categorias', $this->Categoria->find('all', 
361
				array('conditions' => 
362
					array('ativo' => 1,
363
						  'usuario_id' => $this->instancia
364
					)
365
				)
366
			)
367
		);	
368
	}
369
370
	public function s_editar_cadastro($id) {
0 ignored issues
show
Coding Style introduced by
s_editar_cadastro uses the super-global variable $_FILES which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
371
		$dados = $this->request->data('dados');
372
373
		$variacoes = $this->request->data('variacao');
374
375
		$image  = $_FILES['imagem'];
376
		
377 View Code Duplication
		if (!empty($image['name'])) {
378
			$retorno = $this->uploadImage($image);
379
			
380
			if (!$retorno['status']) 
381
				$this->Session->setFlash('Não foi possivel salvar a imagem tente novamente');
382
			
383
			$dados['imagem'] = $retorno['nome'];
384
		}
385
386
387
		$dados['id_usuario'] = $this->instancia;
388
		$dados['ativo'] = 1;
389
		$dados['id_alias'] = $this->id_alias();
390
391
		$this->Produto->id = $id;
392
		
393
		if ($this->Produto->save($dados)) {
394
395
			require 'VariacaoController.php';
396
			$objVariacaoController = new VariacaoController();
397
			$objVariacaoController->desativar_variacoes($id);
398
			$objVariacaoController->s_adicionar_variacao($variacoes, $id, $this->instancia);	
399
400
			$this->Session->setFlash('Produto editado com sucesso!','default','good');
401
            return $this->redirect('/produto/listar_cadastros');
402
		} else {
403
			$this->Session->setFlash('Ocorreu um erro ao editar o produto!','default','good');
404
            return $this->redirect('/produto/listar_cadastros');
405
		}
406
	}
407
408 View Code Duplication
	public function excluir_cadastro() {
409
		$this->layout = 'ajax';
410
411
		$id = $this->request->data('id');
412
413
		$dados = array('ativo' => '0');
414
		$parametros = array('id' => $id);
415
416
		if ($this->Produto->updateAll($dados, $parametros)) {
417
			echo json_encode(true);
418
		} else {
419
			echo json_encode(false);
420
		}
421
	}
422
423
	public function id_alias() {
424
		$id_alias = $this->Produto->find('first', array(
425
				'conditions' => array('Produto.ativo' => 1),
426
				'order' => array('Produto.id' => 'desc')
427
			)
428
		);
429
430
		return $id_alias['Produto']['id_alias'] + 1;
431
	}
432
433
	public function carregar_dados_venda_ajax() {
434
		$this->layout = 'ajax';
435
436
		$retorno = $this->Produto->find('first', 
437
			array('conditions' => 
438
				array('Produto.ativo' => 1,
439
					  'Produto.id_usuario' => $this->instancia,
440
					  'Produto.id' => $this->request->data('id')
441
				)
442
			)
443
		);
444
445
		if (!$this->validar_estoque($retorno)) {
446
			return false;
447
		}
448
449
		$retorno['Produto']['total'] = $this->calcular_preco_produto_venda($retorno['Produto']['preco'], $this->request->data('qnt'));
450
451
		$retorno['Produto']['preco'] = number_format($retorno['Produto']['preco'], 2, ',', '.');
452
		
453
		echo json_encode($retorno);
454
	}
455
456 View Code Duplication
	public function getUserActive($id) {
457
		$this->loadModel('Usuario');
458
459
		$user = $this->Usuario->find('all', 
460
			array('conditions' => 
461
				array('Usuario.id' => $id)
462
			)
463
		);
464
		
465
		return $user;
466
	}
467
468
	public function validar_estoque($produto) {
469
470
		$user_active = $this->getUserActive($produto['Produto']['id_usuario']);
471
472
		if ($user_active[0]['Usuario']['sale_without_stock'])
473
			return true;
474
475
		if (empty($produto) && !isset($produto)) {
476
			return false;
477
		}
478
		
479
		if ($produto['Produto']['estoque'] <= 0) {
480
			return false;
481
		}
482
483
		return true;
484
	}
485
486
	public function calcular_preco_produto_venda($preco, $qnt) {
487
		if (empty($preco) || !isset($preco)) {
488
			return false;
489
		}
490
491
		if (!is_numeric($qnt)) {
492
			return false;
493
		}
494
495
		$retorno = $preco * $qnt;
496
497
		return number_format($retorno, 2, ',', '.');
498
	}
499
500 View Code Duplication
	public function uploadImage(&$image) {
501
		$type = substr($image['name'], -4);
502
		$nameImage = uniqid() . md5($image['name']) . $type;
503
		$dir = APP . 'webroot/uploads/produto/imagens/';
504
		
505
		$returnUpload = move_uploaded_file($image['tmp_name'], $dir . $nameImage);
506
507
		if (!$returnUpload)
508
			return array('nome' => null, 'status' => false);
509
510
		return array('nome' => $nameImage, 'status' => true);
511
	}
512
513
	public function visualizar_cadastro($id) {
514
		$this->layout = 'wadmin';
515
516
		$produto = $this->Produto->find('all', 
517
			array('conditions' => 
518
				array('ativo' => 1,
519
					  'id' => $id
520
				)
521
			)
522
		);
523
524
		if (empty($produto)) {
525
			$this->Session->setFlash("Produto não encotrado, tente novamente");
526
			$this->redirect("/produto/listar_cadastros");
527
		}
528
529
		$this->set('produto', $produto[0]);
530
	}
531
532
	public function exportar_excel_exemplo() {
533
		include(APP . 'Vendor/PHPExcel/PHPExcel.php');
534
		include(APP . 'Vendor/PHPExcel/PHPExcel/IOFactory.php');
535
536
        $objPHPExcel = new PHPExcel();
537
        // Definimos o estilo da fonte
538
        $objPHPExcel->getActiveSheet()->getStyle('A1')->getFont()->setBold(true);
539
540
        $objPHPExcel->getActiveSheet()->getRowDimension('1')->setRowHeight(40);
541
542
        // Criamos as colunas
543
        $objPHPExcel->setActiveSheetIndex(0)
0 ignored issues
show
Bug introduced by
The method setCellValue does only exist in PHPExcel_Worksheet, but not in PHPExcel_Cell.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
544
                    ->setCellValue('A1', "Nome do Produto")
545
                    ->setCellValue('B1', "Preço ")
546
                    ->setCellValue("C1", "Peso Bruto")
547
                    ->setCellValue("D1", "Peso Liquido")
548
                    ->setCellValue("E1", "Estoque")
549
                    ->setCellValue("F1", "Descrição");
550
551
        // Podemos renomear o nome das planilha atual, lembrando que um único arquivo pode ter várias planilhas
552
        $objPHPExcel->getActiveSheet()->setTitle('Listagem de produtos');
553
554
        // Cabeçalho do arquivo para ele baixar
555
        header('Content-Type: application/vnd.ms-excel');
556
        header('Content-Disposition: attachment;filename="planilha_importacao_exemplo.xls"');
557
        header('Cache-Control: max-age=0');
558
        // Se for o IE9, isso talvez seja necessário
559
        header('Cache-Control: max-age=1');
560
561
        // Acessamos o 'Writer' para poder salvar o arquivo
562
        $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
563
564
        // Salva diretamente no output, poderíamos mudar arqui para um nome de arquivo em um diretório ,caso não quisessemos jogar na tela
565
        $objWriter->save('php://output'); 
566
567
        exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The method exportar_excel_exemplo() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
568
    }
569
570
    public function importar_produtos_planilha() {
0 ignored issues
show
Coding Style introduced by
importar_produtos_planilha uses the super-global variable $_FILES which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
571
        if (!isset($_FILES['arquivo']['tmp_name']) && empty($_FILES['arquivo']['tmp_name']))
572
        {
573
			$this->Session->setFlash("Erro ao subir a planilha, tente novamente.");
574
			$this->redirect("/produto/listar_cadastros");        	
575
        }
576
577
        $typesPermissions = ['application/vnd.ms-excel'];
578
579
        if (!in_array($_FILES['arquivo']['type'], $typesPermissions))
580
        {
581
			$this->Session->setFlash("O arquivo deve ser no formato .xls.");
582
			$this->redirect("/produto/listar_cadastros");                	
583
        }
584
585
        $caminho = APP . 'webroot/uploads/produto/planilhas/' . uniqid() . '.xls';
586
587
        $inputFileName = $_FILES['arquivo']['tmp_name'];
588
589
        move_uploaded_file($inputFileName, $caminho);
590
591
        $data = [
592
        	'caminho' => $caminho,
593
        	'usuario_id' => $this->instancia,
594
        	'processado' => 0,
595
        	'ativo' => 1
596
        ];
597
598
        $this->loadModel('QueueProduct');
599
600
        if ($this->QueueProduct->save($data))
601
        {
602
			$this->Session->setFlash("O arquivo está na fila para ser importado, iremos enviar um e-mail quando terminar.");
603
			$this->redirect("/produto/listar_cadastros");  
604
        }
605
        else 
606
        {
607
			$this->Session->setFlash("Ocorreu um erro, tente novamente.");
608
			$this->redirect("/produto/listar_cadastros");          	
609
        }
610
    }
611
612
    public function processar_planilhas_na_fila() {
613
    	$this->loadModel('QueueProduct');
614
615
    	$planilhas = $this->QueueProduct->loadPlanilhasNotProcesseds();
616
617
    	$response = [];
618
    	foreach ($planilhas as $planilha) {
619
    		$response[] = $this->processar_planilhas($planilha['caminho'], $planilha['usuario_id'], $planilha['id']);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $response[] is correct as $this->processar_planilh..._id'], $planilha['id']) (which targets ProdutoController::processar_planilhas()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
620
    	}
621
622
    	return $response;
623
    }
624
625
    public function processar_planilhas($inputFileName, $usuarioId, $planilhaId) {
626
		include(APP . 'Vendor/PHPExcel/PHPExcel.php');
627
		include(APP . 'Vendor/PHPExcel/PHPExcel/IOFactory.php');
628
    	
629
        $objPHPExcel = new PHPExcel();
630
631
		try {
632
		    $inputFileType 	= PHPExcel_IOFactory::identify($inputFileName);
633
		    $objReader 		= PHPExcel_IOFactory::createReader($inputFileType);
634
		    $objPHPExcel 	= $objReader->load($inputFileName);
635
		} catch(Exception $e) {
636
		    die('Error loading file "' . pathinfo($inputFileName, PATHINFO_BASENAME) . '": ' . $e->getMessage());
0 ignored issues
show
Coding Style Compatibility introduced by
The method processar_planilhas() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
637
		}
638
639
		$dados = [];
640
641
		$rows = $objPHPExcel->setActiveSheetIndex(0)->getHighestRow();
642
643
		for ($row = 2; $row <= $rows; $row++) {
644
			
645
			$rowInterator = $objPHPExcel->getActiveSheet()->getRowIterator($row)->current();
646
647
			$cellIterator = $rowInterator->getCellIterator();
648
			$cellIterator->setIterateOnlyExistingCells(false);
649
650
			foreach ($cellIterator as $i => $cell) {
651
				switch ($i) {
652
					case 0: //Codigo/SKU
653
						$dados[$row]['sku'] = $cell->getValue();
654
					break; 
655
					case 1: // Nome/Descrição 
656
						$dados[$row]['nome'] = $cell->getValue();						
657
					break;
658
					case 2: // QtdAtual
659
						//$dados[$row]['sku'] = $cell->getValue();						
660
					break;
661
					case 3: // QtdMinima  
662
						$dados[$row]['quantidade_minima'] = $cell->getValue();						
663
					break;
664
					case 4: // QtdTotal
665
						$dados[$row]['estoque'] = $cell->getValue();						
666
					break;
667
					case 5: // ValCusto
668
						$dados[$row]['custo'] = $cell->getValue();						
669
					break;
670
					case 6:  // ValVenda
671
						$dados[$row]['preco'] = $cell->getValue();						
672
					break;
673
				}
674
			}
675
676
			$dados[$row]['id_usuario'] = $usuarioId;	
677
			$dados[$row]['ativo'] = 1;
678
679
		}
680
681
		$errors = $this->processar_lista_produtos($dados);
682
683
		if (isset($errors) && !empty($errors))
684
		{
685
			$this->QueueProduct->planilhaProcessedIncomplete($planilhaId);
686
		}
687
688
		$this->QueueProduct->planilhaProcessedComplete($planilhaId);
689
690
		echo json_encode(array('sucess' => true));
691
		exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The method processar_planilhas() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
692
    }
693
694
    public function processar_lista_produtos($dados) {
695
    	$errors = [];
696
697
    	foreach ($dados as $dado) {
698
    		$this->loadModel('Produto');
699
    		
700
    		$existProduto = $this->Produto->find('all',
701
    			array(
702
    				'conditions' => array(
703
    					'Produto.sku' => $dado['sku'],
704
    					'Produto.ativo' => 1
705
    				)
706
    			)
707
    		);
708
709
    		if (isset($existProduto) && !empty($existProduto))
710
    		{
711
    			$this->Produto->id = $existProduto[0]['Produto']['id'];
712
    			$this->Produto->save($dado);
713
    			continue;
714
    		}
715
716
			$this->Produto->create();
717
718
    		if (!$this->Produto->save($dado))
719
    		{
720
    			$errors[] = $dado;
721
    		}
722
    	}
723
724
    	return $errors;
725
    }
726
727
}
728