ENGLISH
- How to create an SMS Signup form with PHP (Part 1) ?
TÜRKÇE
Merhaba arkadaşlar,
SMS, hemen hemen herkes tarafından cep telefonu kullanılan dünya çapında bir teknolojidir. Akıllı telefon pazarına göre çok daha geniş bir alana sahip olmasına rağmen, SMS programlama çok daha az ücret alır ve genellikle kapitalize edilmemiş olarak kalır. Bu çok bölümlü öğreticide, kullanıcıların bir mobil numara girmesine izin veren bir web sitesi kayıt formu nasıl oluşturulacağını göstereceğim. Sonra, kullanıcıya girmiş olduğunuz cep numarasının aslında cep telefonunun olup olmadığını kontrol etmek için PHP'yi sunucu tarafı telefon numarası doğrulaması için nasıl kullanacağınızı göstereceğim. Yol boyunca, istemci tarafında doğrulama yapmak için jQuery'yi ve geliştirme çerçevemiz olarak CodeIgniter'yi kullanacağız.
1- PLANLAMA
Çözümün genel bir bakışıyla başlayalım. Kullanıcı bir kayıt formuna erişir, bir ülke seçer ve bir cep telefonu numarası girer. Kaydolma formunu gönderdikten sonra, kullanıcının yeni hesabı etkinleştirmek için girilen cep telefonu numarasına bir doğrulama kodu girmesi gerekir. Kullanıcı, doğrulama kodunu girmeden önce sayfayı kapatır ve daha sonra kayıt formunu onaylarsa, telefon kodu formu yine de görüntülenir.Hadi başlayalım :)
2- CODELGNITER İNDİRME
http://www.codeigniter.com adresinden CodeIgniter'ı indirin. Sonra, klasörü çıkarın ve web sunucunuzun webrootuna kopyalayın. Webroot'unuza kopyalama isteğe bağlıdır, ancak bunu yaparak kaynak dosyalar arasında daha iyi gezinebilmemize yardımcı oluruz.
- Uygulama dizininde config dizinine gidin ve config.php dosyasını açın. Bu, aşağıdaki kodda olduğu gibi bazı ayarlarını yapmamız gereken ana yapılandırmadır:
$config['base_url'] = "http://localhost/sending_sms/";
...
$config['index_page'] = "index.php";
...
$config['uri_protocol'] = "AUTO";
Sonra, aynı config klasöründe database.php dosyasını açın ve aşağıdaki görevleri tamamlayın:
db['default']['hostname'] = "localhost";
$db['default']['username'] = "root";
$db['default']['password'] = "__password__";
$db['default']['database'] = "sms_users";
Son olarak, config klasöründe autoload.php dosyasını açıp, ihtiyacımız olan bazı kütüphaneleri ve yardımcıları ekleyelim:
$autoload['libraries'] = array('database');
...
$autoload['helper'] = array('url', 'form', 'cookie');
3- KAYIT DENETLEYİCİSİ
Kaydolma denetleyicisi oluşturalım. Application/controllers klasöründe signup.php adlı bir dosya oluşturun ve ana kayıt işlevselliğini kodlamaya başlayalım:
class Signup extends Controller {
function Signup(){
parent::Controller();
}
function index(){
$this->load->view('signup' );
}
}
Signup sınıfını oluşturdum, dosyayla aynı adı taşıdığını ve denetleyiciyi genişlettiğini farkedeceksiniz. Kayıt formu ekranını işleyecek olan index () işlevi yarattım. Buna dizin adı veriyoruz çünkü bu varsayılan url'ye erişirken herhangi bir segment olmadan çağrılan varsayılan işlevdir. Ayrıca config/routes.php'de varsayılan denetleyiciyi (kayıt) yapılandırmak zorundayız:
$route['default_controller'] = "signup";
Uygulamayı şimdi test ederseniz, 'İstenen dosyayı yükleyemiyoruz: signup.php' şeklinde bir hata mesajı alırsınız. Bunun nedeni, kayıt görünümü oluşturmadığımız gerçeğidir. Şimdi kayıt görünümü oluşturalım...
4- KAYIT GÖRÜNÜMÜ OLUŞTURMA
Apllication/views klasörüne yeni bir dosya signup.php oluşturun ve aşağıdaki kodları girin:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Signup</title>
<link rel="stylesheet" href="<?php echo base_url(); ?>css/reset.css" type="text/css" />
<link rel="stylesheet" href="<?php echo base_url(); ?>css/design.css" type="text/css" />
</head>
<body>
<div id="wrap">
<h2>Signup form</h2>
<?php echo validation_errors('<div class="error">', '</div>'); ?>
<?php echo form_open('signup/process', array('id'=>'form') ); ?>
<?php echo form_label('Name:', 'name'); ?>
<?php echo form_input( array('name'=>'name', 'id'=>'name', 'class'=>'required', 'value'=>set_value('name') ) ); ?>
<?php echo form_label('Email:', 'email'); ?>
<?php echo form_input( array('name'=>'email', 'id'=>'email', 'class'=>'required email', 'value'=>set_value('email') ) ); ?>
<?php echo form_label('Country:', 'country'); ?>
<?php echo form_dropdown('country', $countries, '','id="country" class="required"' ); ?>
<?php echo form_label('Mobile phone:', 'mobile'); ?>
<div><?php echo form_input( array('name'=>'prefix', 'id'=>'prefix', 'value'=>set_value('prefix') ) ); ?>
<?php echo form_input( array('name'=>'mobile', 'id'=>'mobile', 'class'=>'required digits', 'value'=>set_value('mobile') ) ); ?>
</div>
<div align="center"><?php echo form_submit('register', 'Register', 'class="submit"' ); ?></div>
</div>
</body>
</html>
Biçimlendirmeden bazılarını açıklayayım. Başta her zamanki meyerweb sıfırlama CSS kurallarına ve sonradan kodlayacağımız bir design.css dosyasına sahip bir reset.css dosyası ekledim. Bu ikisini 'css' adlı kök dizindeki bir klasöre koydum. Görünüm dosyasında kök elde etmek için base_url () kullanıyorum. Form yardımcısını formun açılmasını oluşturmak için kullandım, formun kimliğini verirken aynı form yardımcısını kullanarak birkaç etiket ve giriş oluşturdum. Bir dizi, id veya sınıf anahtarlarıyla form_input () işlevinin ikinci parametresi olarak geçtiğimi fark edeceksiniz. Form yardımcısını kullanma hakkında daha fazla bilgi için CodeIgniter belgelerini okuyun. Form_dropdown () yöntemini , $ countries adında bir dizi seçenek geçiren bir seçim kutusu oluşturmak için kullandım. Bu dizine henüz sahip değiliz, ancak biraz daha ilerleyeceğiz.
5- CSS'YE KAYDOLMA
Css dizininde design.css dosyasını oluşturun ve apllication/views klasörüne koyun ve aşağıdaki css kurallarını girin:
body {
background-color: #CFCFCF;
padding: 0px;
margin: 0px;
font-size: 12px;
font-family: Helvetica, Verdana, Arial, sans-serif;
}
#wrap {
width: 400px;
margin-left: auto;
margin-right: auto;
margin-top: 40px;
background-color: #ECECEC;
border: solid 1px #FCFCFC;
padding: 10px;
}
h2 {
margin-bottom: 10px;
font-size: 18px;
}
label {
display: block;
}
input, select {
width: 380px;
padding: 5px;
margin-bottom: 10px;
}
select {
width: 390px;
}
#prefix {
width: 50px;
margin-right: 10px;
margin-bottom: 0px;
display:inline;
}
#mobile {
width: 305px;
display:inline;
}
input.submit {
background-color: #E0E0E0;
border: solid 1px #C5C5C5;
width: 140px;
font-weight: bold;
margin-top: 10px;
}
input.error, select.error {
margin-bottom: 0px;
border: solid 1px #FFCCCC;
}
div.error {
padding: 5px;
background-color: #ffeeee;
border: solid 1px #FFCCCC;
color: #ff0000;
}
div.ok {
padding: 5px;
background-color: #CCFFCC;
border: solid 1px #44CC44;
color:#336633;
margin-bottom: 10px;
}
Yatay kaydırma div stilini oluşturdum, kenar boşluğunu sola ve kenar boşluğunu sağa doğru ayarlayarak ortalayabilirsiniz. Daha sonra girdileri tüm tarayıcılarda tutarlı olduklarından emin olduktan sonra 3 hata sınıfı oluşturdum: .error, .ok ve input.error. Bunu jQuery doğrulama eklentisi ile kullanacağız. Ayrıca stil oluşturmak için gerekli hissettiğim 5px dolgu kullandım.
6- ÜLKELER VE ÖRNEKLER
Şimdi test ederseniz, 'tanımsız değişken ülkeler' ve 'foreach () için geçersiz argüman sağlandı' şeklinde bir bildirim alacaksınız. Ülkeleri nasıl ekleyebiliriz? Bunları doğrudan seçime gömebiliriz, bunun yerine bir yapılandırma dosyası kullanırız. Bu, herhangi bir ülke kodunu kolay ve hızlı bir şekilde değiştirebilmemizi sağlar. Ülke kodlu tabloyu countrycode.org'dan yeni bir dosyaya kopyaladım ve tüm içeriği tek bir dizede işlemek için akıllıca bir jQuery kullanarak bana son yapılandırma dosyasını verdim. Ayrıntılara girmeyeceğim. Application/config klasöründe 'countries.php' adlı yeni bir dosya oluşturun ve aşağıdaki modeli kullanarak #config dizinindeki ülkeleri ekleyin:
$config = array();
$config[''] = '';
$config['93'] = 'Afghanistan';
$config['355'] = 'Albania';
$config['213'] = 'Algeria';
...
$config['967'] = 'Yemen';
$config['260'] = 'Zambia';
$config['263'] = 'Zimbabwe';
Dizideki önek kodlarını anahtarlar olarak kullandım. Bu görüşe göre nasıl erişebiliriz? Bu belirli yapılandırma dosyasını, daha önce oluşturduğumuz denetleyici işlev dizininde () yükleyeceğiz:
function index(){
$this->config->load('countries', true);
$data['countries'] = $this->config->item('countries');
$this->load->view('signup', $data );
}
'$this->config->load()' komutunu kullanarak yapılandırmayı yükledim. İkinci parametre olarak da geçerim fark edeceksiniz. Bu, genel yapılandırmada 'ülkeler' adı verilen ayrı bir giriş yapar. Doğruyu geçmezsek, yapılandırma ayarları (yapılandırmadan gelen dizi) genel yapılandırma dizisine eklenir. Bundan sonra yapılandırma öğesini $data['countries'] alanına atadık ve daha sonra view tarafından $country olarak tanıttık. Ayrıca, $data dizisini ikinci parametre olarak görünümde de iletirim. Sayfayı şimdi test ederseniz, seçim kutusundaki tüm ülkeleri alabilirsiniz.
7- jQuery İLE DOĞRULAMA
Biraz jQuery yapma zamanı. Bunun için jquery Validation eklentisini kullanacağız. Bu eklenti Microsoft'un CDN'sinde zaten yer almış durumda, ayrıca Google'ın CDN'deki jQuery'yi buradan alacağız. Sınıfları doğrudan html'ye yazmak için metadata eklentisine ihtiyacımız var:
Doğrulama eklentisi, girdiye bir sınıf adı vererek çalışır. Boş olmayan değerleri istemek için gerekli, bir e-posta adresinin doğrulanması için e-posta, sayısal girdilerin basamakları ve sayı limiti. Girişlerdeki sınıfları kodladığımın farkına varacaksınız, başlangıçtaki html'ye bakmanız yeterlidir. Şimdi test ederseniz, girdikten sonra css'de kodladığım bir .error sınıfıyla bir hata divı geldiğini göreceksiniz . Ayrıca, geçerli olmayan girdiye bir .error sınıfı da atandığından, input.error sınıfını da kodladım . Bu, kullanıcının JavaScript'i etkinse formu doğrular.
8- ÜLKE SEÇİMİNE DAYALI TELEFON ÖN EKİ DEĞİŞTİRME
Artık kullanıcı bir ülke seçtiğinde ön ek girişinin değerini değiştirmek için akıllı bir etkinlik kullanacağız. Bu, arka planda olduğu gibi yalnızca görsel amaçlar için yapılır, ön eki ülke değerinden alır, ancak bu kullanıcıya telefonunu nasıl gireceğini gösterir. Şimdi bunu yapalım:
<script type="text/javascript">
$(document).ready( function(){
$('#form').validate( {'errorElement': 'div' } );
//ülke seçimi esasına göre ön eki değiştirin
$('#country').change( function(){
$('#prefix').val( $('#country option:selected').val() );
});
});
</script>
Tamam, bu yüzden seçimin değişim olayına bir işlev yarattım ve seçili seçeneğin değerini ön ek giriş değerine atadım. Önemli bir şey değil, ancak kaydolma formumuzu gerçekten kolaylaştırıyor.
Kayıt görünümünde ihtiyacımız olan tek şey bu. Aktivasyon işlevini oluşturup görelim.
9- ETKİNLEŞTİRME KODU GÖRÜNÜMÜ
Bu, başarıyla kaydolduktan sonra kullanıcının göreceği sayfadır. Ona, girmesi gereken bir kodu kendisine gönderdiği gibi, cep telefonunu kontrol etmesini söyleyen bir mesaj olacaktır. Signup.php denetleyicisinde activate() adı verilen yeni bir işlev oluşturun:
function activate(){
$data = array();
$data['error'] = '';
$this->load->view('activate', $data );
}
Etkinleştirme yanlış olduğunda, görünümde kullanılacak bir hata değişkeni tanımladım. Bu sayfaya, kullanıcı bilgilerini başarıyla girdikten ve SMS gönderdikten sonra erişilecektir. Ayrıca, application/views klasöründe activate.php adlı yeni bir dosya oluşturur ve aşağıdaki biçimlendirmeyi gireriz:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Activate</title>
<link rel="stylesheet" href="<?php echo base_url(); ?>css/reset.css" type="text/css" />
<link rel="stylesheet" href="<?php echo base_url(); ?>css/design.css" type="text/css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.microsoft.com/ajax/jquery.validate/1.7/jquery.validate.min.js"></script>
<script type="text/javascript" src="<?php echo base_url(); ?>js/jquery.metadata.js"></script>
<script type="text/javascript">
$(document).ready( function(){
$('.ok').hide().fadeIn(800);
$('#form').validate( {'errorElement': 'div' } );
});
</script>
</head>
<body>
<div id="wrap">
<h2>Confirm mobile phone</h2>
<div class="ok">Hesabiniz olusturuldu. 5 haneli dogrulama kodu gonderildi. Uyelik islemlerini tamamlamak icin lutfen gelen kodu girim:</div>
<?php echo $error; ?>
<?php echo form_open('signup/activate', array('id'=>'form') ); ?>
<?php echo form_label('Code:', 'code'); ?>
<?php echo form_input( array('name'=>'code', 'id'=>'code', 'class'=>'required digits', 'value'=>set_value('code') ) ); ?>
<div align="center"><?php echo form_submit('signup', 'Complete signup', 'class="submit"' ); ?></div>
<hr />
SMS mesaji gelmediyse <a href="#">buraya tiklayin</a> tekrar gondermek icin
</div>
</body>
</html>
Kodlama burada oldukça basit. Aynı jQuery ve doğrulama eklentisini ekledim. Document.ready olayının içinde, ilk sayfada olduğu gibi jquery.validate() çağırdım . Yetkilendirme kodunu doğrulamak için validate kullanacağız. Ayrıca, başarı mesajı göstermek için ileti bölümünü girdim. Ayrıca, giriş alanını sayılara ve boşa gitmeyen değerlere sığdırmak için 'required' ve 'digits' sınıfı bir ad da koydum. Kullanıcıya aktivasyon kodunu tekrar gönderme seçeneği olan bir mesaj da var, ancak temel kayıtlara çok benzediğinden bu işleve girmeyeceğim.
10- process()
ARKA PLAN İŞLEVİ
Verileri işleyecek ve veritabanına ekleyecek fonksiyonu oluşturalım. Ayrıca doğrulama kütüphanesini de kullanacağız. Sunucuda doğrulama yapılması önemlidir, çünkü bazı insanlar JavaScript'i kapatabilir ve bu nedenle doğrulama çalışmaz. Bu, tabloda geçersiz bir veri bulunmayacağımızı garanti eden bir geri dönüş. Fonksiyon süreci aşağıda verilmiştir:
function process(){
$this->load->library('form_validation');
if ( $this->form_validation->run() ){
$signup = array();
$signup['name'] = $this->input->post('name');
$signup['email'] = $this->input->post('email');
$signup['country'] = $this->input->post('country');
$signup['mobile'] = $this->input->post('country').$this->input->post('mobile');
//generate the unique activation code
mt_rand();
$signup['activation'] = rand( 11111, 99999 );
//insert into db
$this->db->insert('users', $signup );
//send auth sms
set_cookie('signed', $this->db->insert_id(), 86500 );
//redirect
redirect('signup/activate');
} else {
$this->config->load('countries', true);
$data['countries'] = $this->config->item('countries');
$this->load->view('signup', $data );
}
}
Şimdi tüm önemli kısımları inceleyelim:
Önce form doğrulama kütüphanesini yükledik. Bundan sonra doğru değerlerini kontrol etmek için form validasyonunun run() fonksiyonunu kullanıyoruz. Tüm girdiler geçerse, $this->input->post('input_name')
kullanarak tüm gönderim verileriyle bir dizi oluşturur ve verileri kullanıcılardan oluşan bir tabloya ekleriz, bunu da biraz sonra yapacağız. Burada dikkat edilmesi gereken bir husus, auth kodunu da oluşturmamdır. Kullanıcıya rastgele ve benzersiz 5 haneli doğrulama kodu üretmek için mt_rand() kullanıyorum. 11111 ile 99999 arasında bir sayı üretmek için rand() çalıştırarak bunu yaparız. Bu her zaman bize uzunluk olarak 5 haneli bir sayı verir. 10000'i kullanmadım, çünkü rastgele görünmeyen 10002 gibi, yinelenen bir sayı alabiliriz. Ayrıca, veritabanına kullanıcının kimlik değeri ile 'signed' adlı bir çerez ayarladım ve ardından kullanıcıyı etkinleştirme işlevine yönlendirdim. Bazı alanlar geçersizse, ülkeler tekrar yüklenir ve kayıt görünümü yüklenir. Başlangıçtan itibaren kayıt görünümüne bakarsanız, son kayıttan kullanılan değeri elde etmek için set_value() kullandığımı göreceksiniz . Dolayısıyla, geçersiz bir alan varsa, alanların geri kalan kısmı son verilerle doldurulur. Ancak, kayıt görünümünde güncellenecek bir satır var:
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left"><?php echo form_dropdown('country', $countries, @$_POST['country'],'id="country" class="required"' );</span> <? php echo form_dropdown ('ülke', $ ülkeler, @ $ _ POST ['ülke'], 'id = "ülke" sınıfı = "gerekli"');</span> <span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">?></span> ?></span>
Üçüncü parametreyi, @ ile bir bildirim göstermediğinden emin olarak, $ _POST['ülke'] ile değiştirdim. Bu, select seçeneğini, göndermeden önce seçilen seçeneğe ayarlar. Data verilerinde bir ülkem yoksa, kayıt başlamasında olduğu gibi bir şey seçmeyeceğiz.
11- DOĞRULAMA KURALLARI
Doğrulama kurallarını oluşturmamız gerekiyor. Neyse ki, CodeIgniter bunları application/config klasöründeki form_validation.php adlı bir config dosyasına yazmanıza izin verir. Henüz yoksa dosyayı oluşturun ve aşağıdakileri girin:
$config = array(
array('field'=>'name',
'label'=>'Name',
'rules'=>'required'),
array('field'=>'email',
'label'=>'Email',
'rules'=>'required|valid_email|callback_check_email_exists'),
array('field'=>'country',
'label'=>'Country',
'rules'=>'required'),
array('field'=>'mobile',
'label'=>'Mobile phone',
'rules'=>'required|numeric')
);
Doğrulama ile ilgili kuralları belirlemek için bu çok boyutlu diziyi kullanıyorum. Örneğin, ad alanı için, isim alanının kurallarını belirlemek için 'alan' anahtarını, alanın hata mesajında (eğer gösteriliyorsa) adını ayarlamak için kullanılan 'etiket' tuşunu ve 'kurallar' tuşlarını kullanarak kuralları ayarlayın. Kuralları bir boru karakteriyle ayırıyorum (yani '|'). Mevcut kurallar hakkında daha fazla bilgi için kullanım kılavuzundaki form doğrulama belgelerini kontrol edebilirsiniz. Ayrıca e-postanın var olup olmadığını kontrol etmek için kullanıcı tarafından tanımlanan bir geri arama (callback_check_email_exists) oluşturdum. Kural adına callback_ eklenmesi, denetleyicide bir işlev arar ve onu çağırır. Bu işlev, veritabanında aynı e-posta adresinin olup olmadığını kontrol eder ve kaynak şöyledir:
function check_email_exists( $email ){
$rs = $this->db->where( 'email', $email )->count_all_results('users');
$this->form_validation->set_message('check_email_exists', "We're sorry, this email already exists!");
if( $rs < 1 ){
return true;
}
return false;
}
Bu, bir bağımsız değişkeni (denetlenen değer) kabul eden ve biçime bağlı olarak doğru veya yanlış döndüren basit bir işlevdir. Tabloda e-posta adresi ile bir sonuç olup olmadığını kontrol ediyoruz ve eğer varsa, yanlış döndürüyoruz. Doğrulamak istersek doğruya, geçersiz olarak yanlış döndürmeliyiz, böylece işlev adı biraz akward olur.
12- Mysql TABLOSU
Kaynak kodunu indirebilir ve users.sql dosyasından users tablosunu içe aktarabilir veya aşağıdaki komutlarla oluşturabilirsiniz:
CREATE TABLE `users`
( `uid` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`name` TEXT NOT NULL,
`email` TEXT NOT NULL,
`country` INT NOT NULL,
`mobile` TEXT NOT NULL,
`activation` TEXT NOT NULL,
`active` INT NOT NULL,
PRIMARY KEY (`uid`) );
Bu kodu phpMyAdmin'de çalıştırın. Tablo oluşturulacaktır.
Kodu şimdi test ederseniz, tüm geçerliliği doğru bulacaksınız. Sunucu doğrulamasını denemek için JavaScript'i devre dışı bırakabilirsiniz.
Github URL : https://github.com/php/php-src
Posted on Utopian.io - Rewarding Open Source Contributors
Source- https://code.tutsplus.com/articles/create-an-sms-signup-form-part-1--mobile-2457
Not indicating that the content you copy/paste is not your original work could be seen as plagiarism.
Some tips to share content and add value:
Repeated plagiarized posts are considered spam. Spam is discouraged by the community, and may result in action from the cheetah bot.
Creative Commons: If you are posting content under a Creative Commons license, please attribute and link according to the specific license. If you are posting content under CC0 or Public Domain please consider noting that at the end of your post.
If you are actually the original author, please do reply to let us know!
Thank You!
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
In review
You may edit your post here, as shown below:
You can contact us on Discord.
[utopian-moderator]
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Your contribution cannot be approved because it does not follow the Utopian Rules, and is considered as plagiarism. Plagiarism is not allowed on Utopian, and posts that engage in plagiarism will be flagged and hidden forever.
https://code.tutsplus.com/articles/create-an-sms-signup-form-part-1--mobile-2457
You can contact us on Discord.
[utopian-moderator]
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Great
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Nice work
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit