const sonuc = firstArray.map(x=>secondArray.map(y=>[x, y])).flat(1);
veya
const sonuc = [];
firstArray.map(x=>{
sonuc.push(...secondArray.map(y=>[x,y]));
});
veya
const sonuc = [];
for(let i=0; i < firstArray.length; i++) {
for(let k=0; k < secondArray.length; k++) {
sonuc.push([firstArray[i], secondArray[k]);
}
}
Bu işlemi birkaç farklı yerde kullanacaksan fonksiyonlaştırmanı öneririm:
const matchSetsOneToOne = (set1, set2) => set1.map(x=>set2.map(y=>[x, y])).flat(1);
// Kullanırken:
const sonuc = matchSetsOneToOne(firstArray, secondArray);
Muhtemelen $E = self::$connection->query($SQL);
komutunu verdiğiniz sırada henüz $connection
değişkenine değer atanmamış oluyor.
DB::primaryID("test");
satırını çalıştırmadan önce __connect()
fonksiyonunu çalıtırmanız gerekiyor.
Siz __construct()
fonksiyonuyla $connection
değişkeninize değer atıyorsunuz ama primaryID()
class'ı statik olarak çağırdığınızda __construct()
fonksiyonu çağırılmaz.
Hata aldığınız satırdan bir önceki satırda $connection
değerinin null olup olmadığını kontrol etmeli ve buna göre hareket etmelisiniz.
Hata mesajı da bundan bahsediyor: null bir değerden query() diye bir fonksiyon çağırıyorsunuz.
Şu 2 fonksiyon yardımcı olsun:
const convertDate = (str, timezoneDiff) => {
const t = str.split(/[- :]/);
t[1]--;
return new Date(Date.UTC(...t) - 1000 * 60 * 60 * timezoneDiff);
}
const diffDate = (date1, date2) => {
const t = date1-date2;
if(t > 0) return {
days: Math.floor(t / (1000 * 60 * 60 * 24)),
hours: Math.floor((t % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)),
minutes: Math.floor((t % (1000 * 60 * 60)) / (1000 * 60)),
seconds: Math.floor((t % (1000 * 60)) / 1000)
}
return {days:0, hours:0, minutes:0, seconds:0}
}
Şu şekilde kullanalım:
let endDateString = "2022-12-25 15:00:00";
const now = new Date();
const endDate = convertDate(endDateString, 1);
const diff = diffDate(endDate, now);
Buradaki convertDate()
fonkisyonunun
ilk parametresi MySQL datetime formatında gelen string türdeki tarih.
ikinci parametreyi de sunucunun saat dilimi olarak 1 gönderdik. (+1 anlamına geliyor)
Fonksiyon, sunucunun saat dilimini 0'a çekiyor ve sonra yerel saat dilimine (Türkiye için +3) göre js date objesi oluşturuyor.
diffDate()
fonksiyonuna da
ilk parametrede js date objesi olarak sunucudan gelen tarihi,
ikinci parametre olarak da js date objesi olarak şu anki tarihi verdik.
Fonksiyon değerleri hesaplayıp obje halinde return ediyor.
İnceleyebilmeniz için bir örnek:
https://codepen.io/ebykdrms/pen/LYrWEaY
İleride CodePen'den silme ihtimalime karşı kodları buraya da bırakıyorum:
<div id="steps">
<div class="step" data-step-name="step-1">
<label>
<span>Ad</span>
<input name="name" required />
</label>
<label>
<span>Soyad</span>
<input name="surname" required />
</label>
<label>
<span>E-posta</span>
<input name="email" />
</label>
<label>
<span>Cinsiyet</span>
<select name="gender" required>
<option value="" disabled selected>Seçiniz</option>
<option value="Kadın">Kadın</option>
<option value="Erkek">Erkek</option>
</select>
</label>
<button class="nextStepButton">
Devam
<i class="fa-solid fa-chevron-right"></i>
</button>
</div>
<div class="step" data-step-name="step-2" data-step-by="Erkek">
<h2 class="hello"></h2>
<label>
<span>Yaş</span>
<input name="age" />
</label>
<div class="stepButtons">
<button class="prevStepButton">
<i class="fa-solid fa-chevron-left"></i>
Geri
</button>
<button class="nextStepButton">
Devam
<i class="fa-solid fa-chevron-right"></i>
</button>
</div>
</div>
<div class="step" data-step-name="step-2" data-step-by="Kadın">
<h2 class="hello"></h2>
<label>
<span>Maaş</span>
<input name="salary" />
</label>
<div class="stepButtons">
<button class="prevStepButton">
<i class="fa-solid fa-chevron-left"></i>
Geri
</button>
<button class="nextStepButton">
Devam
<i class="fa-solid fa-chevron-right"></i>
</button>
</div>
</div>
<div class="step" data-step-name="step-3">
<div class="info"></div>
<div class="stepButtons">
<button class="prevStepButton">
<i class="fa-solid fa-chevron-left"></i>
Geri
</button>
<button class="nextStepButton">
Onayla
<i class="fa-solid fa-check"></i>
</button>
</div>
</div>
</div>
.step {
display:flex;
flex-direction:column;
padding:5px;
border:1px solid #ddd;
margin:10px;
max-width:300px;
opacity:0;
pointer-events:none;
transition:opacity .3s ease 0s;
}
.step.active {
pointer-events:auto;
opacity:1;
}
.step h2 {
padding:10px 5px;
font-weight:bold;
border-bottom:1px solid #ddd;
margin-bottom:5px;
}
.step label {
display:flex;
flex-direction:column;
padding:5px;
}
.step label input,
.step label select {
padding:5px;
margin-top:5px;
border:1px solid #ccc;
outline:none;
}
.step label input.required,
.step label select.required {
border-color:red;
}
.step .stepButtons {
display:flex;
flex-direction:row;
}
.step button {
cursor:pointer;
transition:opacity ease .1s;
}
.step button:active {
opacity:0.5;
}
.step .nextStepButton {
padding:10px;
margin:5px;
margin-top:20px;
border:1px solid #000;
background:#000;
color:#fff;
flex:2;
}
.step .prevStepButton {
padding:10px;
margin:5px;
margin-top:20px;
border:1px solid #000;
background:#fff;
color:#000;
flex:1;
}
.step .nextStepButton i,
.step .prevStepButton i {
margin:0 5px;
}
.step .info table {
margin:5px;
border:1px solid #ddd;
border-bottom:none;
width:calc(100% - 10px);
}
.step .info table tr td {
padding:5px;
border-bottom:1px solid #ddd;
}
function doValidation($wrapper) {
const $inputs = $wrapper.find("input[required],select[required]");
let validationStatus = true;
for(let i=0; i < $inputs.length; i++) {
const $input = $inputs.eq(i);
console.log($input.val())
if(!$input.val() || $input.val().trim()=="") {
validationStatus = false;
$input.addClass("required");
$input.one("input change", function() {
$(this).removeClass("required");
});
}
}
return validationStatus;
}
const $stepsWrapper = $("#steps");
const $steps = $stepsWrapper.find(".step").clone();
$(".step").remove();
const stepDatas = {};
const getStep = (stepName, stepBy=null) => {
const stepNameQuery = `[data-step-name="${stepName}"]`;
const stepByQuery = stepBy ? `[data-step-by="${stepBy}"]` : "";
return $steps.filter(stepNameQuery+stepByQuery);
}
const activeStep = ($step) => {
$(".step").removeClass("active").remove();
$stepsWrapper.append($step);
setTimeout(()=>{$step.addClass("active");},10);
}
$(document).on("click", ".step .nextStepButton", function(){
const $currentStep = $(this).closest(".step");
if(!doValidation($currentStep)) return;
const stepName = $currentStep.attr('data-step-name');
const stepBy = $currentStep.attr('data-step-by');
if(stepName=="step-1") {
stepDatas.name = $currentStep.find(`input[name="name"]`).val();
stepDatas.surname = $currentStep.find(`input[name="surname"]`).val();
stepDatas.email = $currentStep.find(`input[name="email"]`).val();
stepDatas.gender = $currentStep.find(`select[name="gender"]`).val();
const $targetStep = getStep("step-2", stepDatas.gender);
$targetStep.find('h2').text(`Merhaba ${stepDatas.name} ${stepDatas.surname} ${stepDatas.gender=="Kadın"?"Hanım":"Bey"}`);
activeStep($targetStep);
return;
}
if(stepName=="step-2") {
if(stepBy=="Kadın") {
stepDatas.salary = $currentStep.find(`input[name="salary"]`).val();
}
else {
stepDatas.age = $currentStep.find(`input[name="age"]`).val();
}
const $targetStep = getStep("step-3");
const name = `${stepDatas.name} ${stepDatas.surname}`;
const email = stepDatas.email;
const gender = stepDatas.gender=="Kadın" ? "Hanım" : "Bey";
const salary = stepDatas.salary ?? "";
const age = stepDatas.age ?? "";
$targetStep.find('.info').html(`
<table>
<tr><td>Üye</td><td>${name} ${gender}</td></tr>
<tr><td>E-posta</td><td>${email}</td></tr>
<tr><td>Maaş</td><td>${salary}</td></tr>
<tr><td>Yaş</td><td>${age}</td></tr>
</table>
`);
activeStep($targetStep);
return;
}
if(stepName=="step-3") {
alert("Tamam");
activeStep(getStep("step-1"));
return;
}
});
$(document).on("click", ".step .prevStepButton", function(){
const $currentStep = $(this).closest(".step");
const stepName = $currentStep.attr('data-step-name');
const stepBy = $currentStep.attr('data-step-by');
if(stepName=="step-2") {
activeStep(getStep("step-1"));
return;
}
if(stepName=="step-3") {
activeStep(getStep("step-2", stepDatas.gender));
return;
}
});
activeStep(getStep("step-1"));
SQL sorgunuzdan DISTINCT
ifadesini kaldırıp deneyebilirsiniz.
array_merge()
fonksiyonu ile tek satırda bu birleştirmeyi yapabilirsiniz.
Buradaki mantıkta dizyi ...
operatörü ile açıyoruz ve ortaya çıkan dizileri birleştiriyoruz. PHP 7.4 veya üstü için geçerli
$arr = [
['2020-07','2020-08'],
['2020-09','2020-10'],
['2021-01','2021-02','2021-03']
];
$flattenArr = array_merge(...$arr);
$flattenArr
dizisinin çıktısı:
['2020-07', '2020-08', '2020-09', '2020-10', '2021-01', '2021-02', '2021-03']
array_merge() fonksiyonu: https://www.php.net/manual/en/function.array-merge.php
spread operatörü (...): https://www.phptutorial.net/php-tutorial/php-spread-operator
LastInsertId()
yerine lastInsertId()
yazmanız gerekiyor olabilir.
Teşekkürler yalnız bir sorun var. Puanları eksik hesaplıyor. Bazı öğretmenler bir sınıf iki puan verdikleri için birini geçersiz sayıyor.
SQL sorgunuzda DISTINCT sinif
dediğiniz için veritabanından aynı sınıf sadece 1 kez dönüyor olabilir.
<?php
$classes = [];
foreach($sql as $row) {
if(!isset($classes[$row['sinif']])) $classes[$row['sinif']] = 0;
$classes[$row['sinif']] += intval($row['soru1']) + intval($row['soru2']);
}
?>
<table>
<thead>
<th>
<td>SINIF</td>
<td>T_PUAN</td>
</th>
</thead>
<tbody>
<?php foreach($classes as $className => $totalPuan) { ?>
<tr>
<td><?=$className?></td>
<td><?=$totalPuan?></td>
</tr>
<?php } ?>
</tbody>
</table>
$birlesen = [];
foreach($yetkilerListe as $item) {
if(isset($yetkiler[$item])) $birlesen[$item] = $yetkiler[$item];
else $birlesen[$item] = ["view" => 0, "add" => 0, "edit" => 0, "delete" => 0];
}